Skip to content

Commit

Permalink
alg_update_reference_frame: test harness: directly compare functions
Browse files Browse the repository at this point in the history
Directly run two functions on the same input and check whether they give
the same output; don't just rely on printing a few numbers to the screen
and eyeballing the results.
  • Loading branch information
aklomp committed Sep 10, 2014
1 parent 744b3b0 commit 668930f
Showing 1 changed file with 73 additions and 30 deletions.
103 changes: 73 additions & 30 deletions alg/tests/test_alg_update_reference_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,59 @@ clean (struct context *ctx)
ctx->imgs.motionsize = WIDTH * HEIGHT;
}

static int
equal_output (struct context *ctx, int action, void (*func_a)(struct context *, int), void (*func_b)(struct context *, int))
{
int i, ret = 1;
struct context cxs[2];

for (i = 0; i < 2; i++)
{
/* Copy original context: */
memcpy(&cxs[i], ctx, sizeof(*ctx));
memcpy(&cxs[i].imgs, &ctx->imgs, sizeof(ctx->imgs));

/* Copy the original image structures: */
#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));
CPY(ref)
CPY(out)
CPY(image_virgin)
CPY(smartmask_final)
CPY(ref_dyn)
#undef CPY
}
/* Run both functions on their own copy: */
func_a(&cxs[0], action);
func_b(&cxs[1], action);

/* Compare image outputs: */
#define CMP(x) if (memcmp(cxs[0].imgs.x, cxs[1].imgs.x, sizeof(*cxs[0].imgs.x)) != 0) { ret = 0; goto out; }
CMP(ref)
CMP(ref_dyn)
#undef CMP

out: /* Free memory, return: */
for (i = 0; i < 2; i++) {
free(cxs[i].imgs.ref);
free(cxs[i].imgs.out);
free(cxs[i].imgs.image_virgin);
free(cxs[i].imgs.smartmask_final);
free(cxs[i].imgs.ref_dyn);
}
return ret;
}

static void
permutate (int action, void (*func)(struct context *, int))
permutate (int action, void (*func_a)(struct context *, int), void (*func_b)(struct context *, int))
{
unsigned char ref[16];
unsigned char out[16];
unsigned char image_virgin[16];
unsigned char smartmask_final[16];
uint16_t ref_dyn[16];
#define STRIPSZ 41

unsigned char ref[STRIPSZ];
unsigned char out[STRIPSZ];
unsigned char image_virgin[STRIPSZ];
unsigned char smartmask_final[STRIPSZ];
uint16_t ref_dyn[STRIPSZ];
struct context ctx;
unsigned int ref_cksum;
unsigned int ref_dyn_cksum;

int i, iter_ref_dyn, iter_smartmask, iter_image_virgin, iter_out, iter_ref;

Expand All @@ -76,8 +118,8 @@ permutate (int action, void (*func)(struct context *, int))
ctx.imgs.image_virgin = image_virgin;
ctx.imgs.smartmask_final = smartmask_final;
ctx.imgs.ref_dyn = ref_dyn;
ctx.imgs.size = 16;
ctx.imgs.motionsize = 16;
ctx.imgs.size = STRIPSZ;
ctx.imgs.motionsize = STRIPSZ;

/* For the purposes of the routine, smartmask is zero or nonzero: */
for (iter_smartmask = 0; iter_smartmask < 2; iter_smartmask++) {
Expand All @@ -87,35 +129,35 @@ permutate (int action, void (*func)(struct context *, int))
for (iter_out = 0; iter_out < 2; iter_out++) {
memset(out, iter_out, ctx.imgs.size);

ref_cksum = 0;
ref_dyn_cksum = 0;

for (iter_image_virgin = 0; iter_image_virgin < 256; iter_image_virgin++) {
memset(image_virgin, iter_image_virgin, ctx.imgs.size);

for (i = 0; i < ctx.imgs.size; i++) {
image_virgin[i] = iter_image_virgin + i;
}
/* ref_dyn has a limited range: */
for (iter_ref_dyn = 0; iter_ref_dyn < 10; iter_ref_dyn++) {
for (i = 0; i < 16; i++) {
ref_dyn[i] = iter_ref_dyn + 1;
for (i = 0; i < ctx.imgs.size; i++) {
ref_dyn[i] = iter_ref_dyn + i;
}
for (iter_ref = 0; iter_ref < 256; iter_ref++) {
memset(ref, iter_ref, ctx.imgs.size);
func(&ctx, action);
ref_cksum += ref[0];

for (i = 0; i < 16; i++) {
ref_dyn_cksum += ref_dyn[i];
for (i = 0; i < ctx.imgs.size; i++) {
ref[i] = iter_ref + i;
}
/* For this permutation, check that both functions
* return the same output data: */
if (equal_output(&ctx, action, func_a, func_b) == 0) {
printf("Functions do NOT match!\n");
return;
}
}
}
}
printf("%d %d\n", ref_cksum, ref_dyn_cksum);
}
}
printf("Functions MATCH\n");
}

static void
testsuite (char *name, struct context *ctx, int action, void (*func)(struct context *, int))
timing (char *name, struct context *ctx, int action, void (*func)(struct context *, int))
{
int i;
float total_time = 0.0f;
Expand All @@ -132,8 +174,6 @@ testsuite (char *name, struct context *ctx, int action, void (*func)(struct cont

/* Print bogus value to prevent the loop from being optimized out: */
printf("Value: %d\nTime: %.4f sec\n", ctx->imgs.ref[0], total_time);

permutate(action, func);
}

#define UPDATE_REF_FRAME 1
Expand All @@ -151,9 +191,12 @@ main ()

init(&ctx);

testsuite("plain", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_plain);
testsuite("plain, SSE2 algorithm demo", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_sse2_algo);
testsuite("SSE2", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_sse2);
timing("plain", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_plain);
timing("plain, SSE2 algorithm demo", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_sse2_algo);
timing("SSE2", &ctx, UPDATE_REF_FRAME, alg_update_reference_frame_sse2);

permutate(UPDATE_REF_FRAME, alg_update_reference_frame_plain, alg_update_reference_frame_sse2_algo);
permutate(UPDATE_REF_FRAME, alg_update_reference_frame_plain, alg_update_reference_frame_sse2);

free(ctx.imgs.ref);
free(ctx.imgs.out);
Expand Down

0 comments on commit 668930f

Please sign in to comment.