@@ -55,17 +55,59 @@ clean (struct context *ctx)
5555 ctx -> imgs .motionsize = WIDTH * HEIGHT ;
5656}
5757
58+ static int
59+ equal_output (struct context * ctx , int action , void (* func_a )(struct context * , int ), void (* func_b )(struct context * , int ))
60+ {
61+ int i , ret = 1 ;
62+ struct context cxs [2 ];
63+
64+ for (i = 0 ; i < 2 ; i ++ )
65+ {
66+ /* Copy original context: */
67+ memcpy (& cxs [i ], ctx , sizeof (* ctx ));
68+ memcpy (& cxs [i ].imgs , & ctx -> imgs , sizeof (ctx -> imgs ));
69+
70+ /* Copy the original image structures: */
71+ #define CPY (x ) cxs[i].imgs.x = malloc(ctx->imgs.size * sizeof(*ctx->imgs.x)); memcpy(cxs[i].imgs.x, ctx->imgs.x, ctx->imgs.size * sizeof(*ctx->imgs.x));
72+ CPY (ref )
73+ CPY (out )
74+ CPY (image_virgin )
75+ CPY (smartmask_final )
76+ CPY (ref_dyn )
77+ #undef CPY
78+ }
79+ /* Run both functions on their own copy: */
80+ func_a (& cxs [0 ], action );
81+ func_b (& cxs [1 ], action );
82+
83+ /* Compare image outputs: */
84+ #define CMP (x ) if (memcmp(cxs[0].imgs.x, cxs[1].imgs.x, sizeof(*cxs[0].imgs.x)) != 0) { ret = 0; goto out; }
85+ CMP (ref )
86+ CMP (ref_dyn )
87+ #undef CMP
88+
89+ out : /* Free memory, return: */
90+ for (i = 0 ; i < 2 ; i ++ ) {
91+ free (cxs [i ].imgs .ref );
92+ free (cxs [i ].imgs .out );
93+ free (cxs [i ].imgs .image_virgin );
94+ free (cxs [i ].imgs .smartmask_final );
95+ free (cxs [i ].imgs .ref_dyn );
96+ }
97+ return ret ;
98+ }
99+
58100static void
59- permutate (int action , void (* func )(struct context * , int ))
101+ permutate (int action , void (* func_a )( struct context * , int ), void ( * func_b )(struct context * , int ))
60102{
61- unsigned char ref [16 ];
62- unsigned char out [16 ];
63- unsigned char image_virgin [16 ];
64- unsigned char smartmask_final [16 ];
65- uint16_t ref_dyn [16 ];
103+ #define STRIPSZ 41
104+
105+ unsigned char ref [STRIPSZ ];
106+ unsigned char out [STRIPSZ ];
107+ unsigned char image_virgin [STRIPSZ ];
108+ unsigned char smartmask_final [STRIPSZ ];
109+ uint16_t ref_dyn [STRIPSZ ];
66110 struct context ctx ;
67- unsigned int ref_cksum ;
68- unsigned int ref_dyn_cksum ;
69111
70112 int i , iter_ref_dyn , iter_smartmask , iter_image_virgin , iter_out , iter_ref ;
71113
@@ -76,8 +118,8 @@ permutate (int action, void (*func)(struct context *, int))
76118 ctx .imgs .image_virgin = image_virgin ;
77119 ctx .imgs .smartmask_final = smartmask_final ;
78120 ctx .imgs .ref_dyn = ref_dyn ;
79- ctx .imgs .size = 16 ;
80- ctx .imgs .motionsize = 16 ;
121+ ctx .imgs .size = STRIPSZ ;
122+ ctx .imgs .motionsize = STRIPSZ ;
81123
82124 /* For the purposes of the routine, smartmask is zero or nonzero: */
83125 for (iter_smartmask = 0 ; iter_smartmask < 2 ; iter_smartmask ++ ) {
@@ -87,35 +129,35 @@ permutate (int action, void (*func)(struct context *, int))
87129 for (iter_out = 0 ; iter_out < 2 ; iter_out ++ ) {
88130 memset (out , iter_out , ctx .imgs .size );
89131
90- ref_cksum = 0 ;
91- ref_dyn_cksum = 0 ;
92-
93132 for (iter_image_virgin = 0 ; iter_image_virgin < 256 ; iter_image_virgin ++ ) {
94- memset (image_virgin , iter_image_virgin , ctx .imgs .size );
95-
133+ for (i = 0 ; i < ctx .imgs .size ; i ++ ) {
134+ image_virgin [i ] = iter_image_virgin + i ;
135+ }
96136 /* ref_dyn has a limited range: */
97137 for (iter_ref_dyn = 0 ; iter_ref_dyn < 10 ; iter_ref_dyn ++ ) {
98- for (i = 0 ; i < 16 ; i ++ ) {
99- ref_dyn [i ] = iter_ref_dyn + 1 ;
138+ for (i = 0 ; i < ctx . imgs . size ; i ++ ) {
139+ ref_dyn [i ] = iter_ref_dyn + i ;
100140 }
101141 for (iter_ref = 0 ; iter_ref < 256 ; iter_ref ++ ) {
102- memset (ref , iter_ref , ctx .imgs .size );
103- func (& ctx , action );
104- ref_cksum += ref [0 ];
105-
106- for (i = 0 ; i < 16 ; i ++ ) {
107- ref_dyn_cksum += ref_dyn [i ];
142+ for (i = 0 ; i < ctx .imgs .size ; i ++ ) {
143+ ref [i ] = iter_ref + i ;
144+ }
145+ /* For this permutation, check that both functions
146+ * return the same output data: */
147+ if (equal_output (& ctx , action , func_a , func_b ) == 0 ) {
148+ printf ("Functions do NOT match!\n" );
149+ return ;
108150 }
109151 }
110152 }
111153 }
112- printf ("%d %d\n" , ref_cksum , ref_dyn_cksum );
113154 }
114155 }
156+ printf ("Functions MATCH\n" );
115157}
116158
117159static void
118- testsuite (char * name , struct context * ctx , int action , void (* func )(struct context * , int ))
160+ timing (char * name , struct context * ctx , int action , void (* func )(struct context * , int ))
119161{
120162 int i ;
121163 float total_time = 0.0f ;
@@ -132,8 +174,6 @@ testsuite (char *name, struct context *ctx, int action, void (*func)(struct cont
132174
133175 /* Print bogus value to prevent the loop from being optimized out: */
134176 printf ("Value: %d\nTime: %.4f sec\n" , ctx -> imgs .ref [0 ], total_time );
135-
136- permutate (action , func );
137177}
138178
139179#define UPDATE_REF_FRAME 1
@@ -151,9 +191,12 @@ main ()
151191
152192 init (& ctx );
153193
154- testsuite ("plain" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_plain );
155- testsuite ("plain, SSE2 algorithm demo" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_sse2_algo );
156- testsuite ("SSE2" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_sse2 );
194+ timing ("plain" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_plain );
195+ timing ("plain, SSE2 algorithm demo" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_sse2_algo );
196+ timing ("SSE2" , & ctx , UPDATE_REF_FRAME , alg_update_reference_frame_sse2 );
197+
198+ permutate (UPDATE_REF_FRAME , alg_update_reference_frame_plain , alg_update_reference_frame_sse2_algo );
199+ permutate (UPDATE_REF_FRAME , alg_update_reference_frame_plain , alg_update_reference_frame_sse2 );
157200
158201 free (ctx .imgs .ref );
159202 free (ctx .imgs .out );
0 commit comments