checkasm: add float comparison util functions
This commit is contained in:
		
							parent
							
								
									711781d7a1
								
							
						
					
					
						commit
						9d218d573f
					
				@ -27,6 +27,7 @@
 | 
				
			|||||||
#include "checkasm.h"
 | 
					#include "checkasm.h"
 | 
				
			||||||
#include "libavutil/common.h"
 | 
					#include "libavutil/common.h"
 | 
				
			||||||
#include "libavutil/cpu.h"
 | 
					#include "libavutil/cpu.h"
 | 
				
			||||||
 | 
					#include "libavutil/intfloat.h"
 | 
				
			||||||
#include "libavutil/random_seed.h"
 | 
					#include "libavutil/random_seed.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_IO_H
 | 
					#if HAVE_IO_H
 | 
				
			||||||
@ -151,6 +152,78 @@ static struct {
 | 
				
			|||||||
/* PRNG state */
 | 
					/* PRNG state */
 | 
				
			||||||
AVLFG checkasm_lfg;
 | 
					AVLFG checkasm_lfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* float compare support code */
 | 
				
			||||||
 | 
					static int is_negative(union av_intfloat32 u)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return u.i >> 31;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_ulp(float a, float b, unsigned max_ulp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union av_intfloat32 x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x.f = a;
 | 
				
			||||||
 | 
					    y.f = b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_negative(x) != is_negative(y)) {
 | 
				
			||||||
 | 
					        // handle -0.0 == +0.0
 | 
				
			||||||
 | 
					        return a == b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (abs(x.i - y.i) <= max_ulp)
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp,
 | 
				
			||||||
 | 
					                         unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < len; i++) {
 | 
				
			||||||
 | 
					        if (!float_near_ulp(a[i], b[i], max_ulp))
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_abs_eps(float a, float b, float eps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float abs_diff = fabsf(a - b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return abs_diff < eps;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_abs_eps_array(const float *a, const float *b, float eps,
 | 
				
			||||||
 | 
					                         unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < len; i++) {
 | 
				
			||||||
 | 
					        if (!float_near_abs_eps(a[i], b[i], eps))
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float_near_ulp(a, b, max_ulp) || float_near_abs_eps(a, b, eps);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps,
 | 
				
			||||||
 | 
					                         unsigned max_ulp, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < len; i++) {
 | 
				
			||||||
 | 
					        if (!float_near_abs_eps_ulp(a[i], b[i], eps, max_ulp))
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Print colored text to stderr if the terminal supports it */
 | 
					/* Print colored text to stderr if the terminal supports it */
 | 
				
			||||||
static void color_printf(int color, const char *fmt, ...)
 | 
					static void color_printf(int color, const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,17 @@ void checkasm_fail_func(const char *msg, ...) av_printf_format(1, 2);
 | 
				
			|||||||
void checkasm_update_bench(int iterations, uint64_t cycles);
 | 
					void checkasm_update_bench(int iterations, uint64_t cycles);
 | 
				
			||||||
void checkasm_report(const char *name, ...) av_printf_format(1, 2);
 | 
					void checkasm_report(const char *name, ...) av_printf_format(1, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* float compare utilities */
 | 
				
			||||||
 | 
					int float_near_ulp(float a, float b, unsigned max_ulp);
 | 
				
			||||||
 | 
					int float_near_abs_eps(float a, float b, float eps);
 | 
				
			||||||
 | 
					int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp);
 | 
				
			||||||
 | 
					int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp,
 | 
				
			||||||
 | 
					                         unsigned len);
 | 
				
			||||||
 | 
					int float_near_abs_eps_array(const float *a, const float *b, float eps,
 | 
				
			||||||
 | 
					                             unsigned len);
 | 
				
			||||||
 | 
					int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps,
 | 
				
			||||||
 | 
					                                 unsigned max_ulp, unsigned len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern AVLFG checkasm_lfg;
 | 
					extern AVLFG checkasm_lfg;
 | 
				
			||||||
#define rnd() av_lfg_get(&checkasm_lfg)
 | 
					#define rnd() av_lfg_get(&checkasm_lfg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user