[FFmpeg-devel] [PATCH] checkasm/lpc: test compute_autocorr

James Almer jamrial at gmail.com
Sat May 25 16:33:19 EEST 2024


On 5/25/2024 8:58 AM, Rémi Denis-Courmont wrote:
> --
> Change since previous version:
> - Disable test on x86, since the x86 optimisation fails
>    with a suspiciously large and regular error with 10-20% probability.

Weird. The sse2 function is written using inline gcc, so it's pretty 
old. And it seems to do adds and muls using the exact same instructions 
compiler generated output would use on x86_64.

> ---
>   tests/checkasm/lpc.c | 54 ++++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 52 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/checkasm/lpc.c b/tests/checkasm/lpc.c
> index 592e34c03d..38810325ac 100644
> --- a/tests/checkasm/lpc.c
> +++ b/tests/checkasm/lpc.c
> @@ -16,6 +16,7 @@
>    * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>    */
>   
> +#include "libavutil/avassert.h"
>   #include "libavutil/mem_internal.h"
>   
>   #include "libavcodec/lpc.h"
> @@ -57,10 +58,50 @@ static void test_window(int len)
>       bench_new(src, len, dst1);
>   }
>   
> +#if !ARCH_X86
> +static void test_compute_autocorr(ptrdiff_t len, int lag)
> +{
> +    LOCAL_ALIGNED(32, double, src, [5000 + 2 + MAX_LPC_ORDER]);
> +    LOCAL_ALIGNED(16, double, dst0, [MAX_LPC_ORDER + 1]);
> +    LOCAL_ALIGNED(16, double, dst1, [MAX_LPC_ORDER + 1]);
> +
> +    declare_func(void, const double *in, ptrdiff_t len, int lag, double *out);
> +
> +    av_assert0(lag >= 0 && lag <= MAX_LPC_ORDER);
> +
> +    for (int i = 0; i < MAX_LPC_ORDER; i++)
> +        src[i] = 0.;
> +
> +    src += MAX_LPC_ORDER;
> +
> +    for (ptrdiff_t i = 0; i < len; i++) {
> +        src[i] = (double)rnd() / (double)UINT_MAX;
> +    }
> +
> +    call_ref(src, len, lag, dst0);
> +    call_new(src, len, lag, dst1);
> +
> +    for (size_t i = 0; i < lag; i++) {
> +        if (!double_near_abs_eps(dst0[i], dst1[i], EPS)) {
> +            fprintf(stderr, "%zu: %- .12f - %- .12f = % .12g\n",
> +                    i, dst0[i], dst1[i], dst0[i] - dst1[i]);
> +            fail();
> +            break;
> +        }
> +    }
> +
> +    bench_new(src, len, lag, dst1);
> +}
> +#endif
> +
>   void checkasm_check_lpc(void)
>   {
>       LPCContext ctx;
> -    int len = rnd() % 5000;
> +    int len = 2000 + (rnd() % 3000);
> +#if !ARCH_X86
> +    static const int lags[] = { 10, 30, 32 };
> +#endif
> +
>       ff_lpc_init(&ctx, 32, 16, FF_LPC_TYPE_DEFAULT);
>   
>       if (check_func(ctx.lpc_apply_welch_window, "apply_welch_window_even")) {
> @@ -72,6 +113,15 @@ void checkasm_check_lpc(void)
>           test_window(len | 1);
>       }
>       report("apply_welch_window_odd");
> -
>       ff_lpc_end(&ctx);
> +
> +#if !ARCH_X86
> +    for (size_t i = 0; i < FF_ARRAY_ELEMS(lags); i++) {
> +        ff_lpc_init(&ctx, len, lags[i], FF_LPC_TYPE_DEFAULT);
> +        if (check_func(ctx.lpc_compute_autocorr, "autocorr_%d", lags[i]))
> +            test_compute_autocorr(len, lags[i]);
> +        report("compute_autocorr_%d", lags[i]);

report("compute_autocorr");

And outside the loop. check_func() will print each specific run lags 
value when you requests benching.

> +        ff_lpc_end(&ctx);
> +    }
> +#endif
>   }


More information about the ffmpeg-devel mailing list