void run_benchmark()
    {
        gauge::config_set cs = get_current_configuration();
        uint32_t size = cs.get_value<uint32_t>("size");
        uint32_t vectors = cs.get_value<uint32_t>("vectors");

        RUN
        {
            // Make parity vects
            ec_init_tables(vectors, vectors, &a[vectors * vectors], g_tbls);

            for (uint32_t i = 0; i < vectors; ++i)
            {
                gf_vect_dot_prod(size, vectors, g_tbls,
                                 m_symbols_two.data(), m_symbols_one[i]);
            }
        }
    }
int main(int argc, char *argv[])
{
	int i, j, rtest, srcs, m, k, nerrs, r, err;
	void *buf;
	u8 g[TEST_SOURCES], g_tbls[TEST_SOURCES*32], src_in_err[TEST_SOURCES];
	u8 *dest, *dest_ref, *temp_buff, *buffs[TEST_SOURCES];
	u8 a[MMAX*KMAX], b[MMAX*KMAX], d[MMAX*KMAX];
	u8  src_err_list[TEST_SOURCES], *recov[TEST_SOURCES];

	int align, size;
	unsigned char *efence_buffs[TEST_SOURCES];
	unsigned int offset;
	u8 *ubuffs[TEST_SOURCES];
	u8 *udest_ptr;

	printf("gf_vect_dot_prod: %dx%d ", TEST_SOURCES, TEST_LEN);

	mk_gf_field();


	// Allocate the arrays
	for(i=0; i<TEST_SOURCES; i++){
		if (posix_memalign(&buf, 64, TEST_LEN)) {
			printf("alloc error: Fail");
			return -1;
		}
		buffs[i] = buf;
	}

	if (posix_memalign(&buf, 64, TEST_LEN)) {
		printf("alloc error: Fail");
		return -1;
	}
	dest = buf;

	if (posix_memalign(&buf, 64, TEST_LEN)) {
		printf("alloc error: Fail");
		return -1;
	}
	dest_ref = buf;
	
	if (posix_memalign(&buf, 64, TEST_LEN)) {
		printf("alloc error: Fail");
		return -1;
	}
	temp_buff = buf;


	// Test of all zeros
	for(i=0; i<TEST_SOURCES; i++)
		memset(buffs[i], 0, TEST_LEN);

	memset(dest, 0, TEST_LEN);
	memset(temp_buff, 0, TEST_LEN);
	memset(dest_ref, 0, TEST_LEN);
	memset(g, 0, TEST_SOURCES);


	for(i=0; i<TEST_SOURCES; i++)
		gf_vect_mul_init(g[i], &g_tbls[i*32]);

	gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[0], buffs, dest_ref);

	gf_vect_dot_prod(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest);

	if (0 != memcmp(dest_ref, dest, TEST_LEN)){
		printf("Fail zero vect_dot_prod test\n");
		dump_matrix(buffs, 5, TEST_SOURCES);
		printf("dprod_base:"); 
		dump(dest_ref, 25);
		printf("dprod:"); 
		dump(dest, 25);
		return -1;
	}
	else
		putchar('.');

	// Rand data test
	for(rtest=0; rtest<RANDOMS; rtest++){
		for(i=0; i<TEST_SOURCES; i++)
			for(j=0; j<TEST_LEN; j++)
				buffs[i][j] = rand();

		for (i=0; i<TEST_SOURCES; i++)
			g[i] = rand();

		for(i=0; i<TEST_SOURCES; i++)
			gf_vect_mul_init(g[i], &g_tbls[i*32]);

		gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[0], buffs, dest_ref);
		gf_vect_dot_prod(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest);

		if (0 != memcmp(dest_ref, dest, TEST_LEN)){
			printf("Fail rand vect_dot_prod test 1\n");
			dump_matrix(buffs, 5, TEST_SOURCES);
			printf("dprod_base:"); 
			dump(dest_ref, 25);
			printf("dprod:"); 
			dump(dest, 25);
			return -1;
		}

		putchar('.');
	}

	// Rand data test with varied parameters
	for(rtest=0; rtest < RANDOMS; rtest++){
		for (srcs = TEST_SOURCES; srcs > 0; srcs--){
			for(i=0; i<srcs; i++)
				for(j=0; j<TEST_LEN; j++)
					buffs[i][j] = rand();

			for (i=0; i<srcs; i++)
				g[i] = rand();

			for(i=0; i<srcs; i++)
				gf_vect_mul_init(g[i], &g_tbls[i*32]);

			gf_vect_dot_prod_base(TEST_LEN, srcs, &g_tbls[0], buffs, dest_ref);
			gf_vect_dot_prod(TEST_LEN, srcs, g_tbls, buffs, dest);

			if (0 != memcmp(dest_ref, dest, TEST_LEN)){
				printf("Fail rand vect_dot_prod test 2\n");
				dump_matrix(buffs, 5, srcs);
				printf("dprod_base:"); 
				dump(dest_ref, 5);
				printf("dprod:"); 
				dump(dest, 5);
				return -1;
			}

			putchar('.');
		}
	}




	// Test erasure code using gf_vect_dot_prod

	// Pick a first test
	m = 9;
	k = 5;
	if (m > MMAX || k > KMAX)
		return -1;

	gf_gen_rs_matrix(a, m, k);

	// Make random data
	for(i=0; i<k; i++)
		for(j=0; j<TEST_LEN; j++)
			buffs[i][j] = rand();

	// Make parity vects
	for (i=k; i<m; i++) {
		for (j=0; j<k; j++)
			gf_vect_mul_init(a[k*i+j], &g_tbls[j*32]);
#ifndef USEREF
		gf_vect_dot_prod(TEST_LEN,
				k, g_tbls, buffs, buffs[i]);
#else
		gf_vect_dot_prod_base(TEST_LEN,
				k, &g_tbls[0], buffs, buffs[i]);
#endif
	}


	// Random buffers in erasure
	memset(src_in_err, 0, TEST_SOURCES);
	for (i=0, nerrs=0; i<k && nerrs<m-k; i++){
		err = 1 & rand();
		src_in_err[i] = err;
		if (err)
			src_err_list[nerrs++] = i;
	}

	// construct b by removing error rows
	for(i=0, r=0; i<k; i++, r++){
		while (src_in_err[r]) {
			r++; 
			continue;
		}
		for(j=0; j<k; j++)
			b[k*i+j] = a[k*r+j];
	}

	if (gf_invert_matrix((u8*)b, (u8*)d, k) < 0)
		printf("BAD MATRIX\n");
	

	for(i=0, r=0; i<k; i++, r++){
		while (src_in_err[r]) {
			r++; 
			continue;
		}
		recov[i] = buffs[r];
	}

	// Recover data
	for(i=0; i<nerrs; i++){
		for (j=0; j<k; j++)
			gf_vect_mul_init(d[k*src_err_list[i]+j], &g_tbls[j*32]);
#ifndef USEREF
		gf_vect_dot_prod(TEST_LEN,
				k, g_tbls, recov, temp_buff);
#else
		gf_vect_dot_prod_base(TEST_LEN,
				k, &g_tbls[0], recov, temp_buff);
#endif

		if (0 != memcmp(temp_buff, buffs[src_err_list[i]],
					TEST_LEN)){
			printf("Fail error recovery (%d, %d, %d)\n", m, k, nerrs);
			printf("recov %d:",src_err_list[i]); 
			dump(temp_buff, 25);
			printf("orig   :");     
			dump(buffs[src_err_list[i]],25);
			return -1;
		}
	}


	// Do more random tests

	for (rtest = 0; rtest < RANDOMS; rtest++){
		while ((m = (rand() % MMAX)) < 2);
		while ((k = (rand() % KMAX)) >= m || k < 1);

		if (m>MMAX || k>KMAX)
			continue;

		gf_gen_rs_matrix(a, m, k);

		// Make random data
		for(i=0; i<k; i++)
			for(j=0; j<TEST_LEN; j++)
				buffs[i][j] = rand();

		// Make parity vects
		for (i=k; i<m; i++) {
			for (j=0; j<k; j++)
				gf_vect_mul_init(a[k*i+j], &g_tbls[j*32]);
#ifndef USEREF
			gf_vect_dot_prod(TEST_LEN, k, g_tbls, buffs, buffs[i]);
#else
			gf_vect_dot_prod_base(TEST_LEN, k, &g_tbls[0], buffs, buffs[i]);
#endif
		}

		// Random errors
		memset(src_in_err, 0, TEST_SOURCES);
		for (i=0, nerrs=0; i<k && nerrs<m-k; i++){
			err = 1 & rand();
			src_in_err[i] = err;
			if (err)
				src_err_list[nerrs++] = i;
		}
		if (nerrs == 0){  // should have at least one error
			while ((err = (rand() % KMAX)) >= k) ;
			src_err_list[nerrs++] = err;
			src_in_err[err] = 1;
		}

		// construct b by removing error rows
		for(i=0, r=0; i<k; i++, r++){
			while (src_in_err[r]) {
				r++; 
				continue;
			}
			for(j=0; j<k; j++)
				b[k*i+j] = a[k*r+j];
		}

		if (gf_invert_matrix((u8*)b, (u8*)d, k) < 0)
			printf("BAD MATRIX\n");
	
		for(i=0, r=0; i<k; i++, r++){
			while (src_in_err[r]) {
				r++; 
				continue;
			}
			recov[i] = buffs[r];
		}

		// Recover data
		for(i=0; i<nerrs; i++){
			for (j=0; j<k; j++)
				gf_vect_mul_init(d[k*src_err_list[i]+j], &g_tbls[j*32]);
#ifndef USEREF
			gf_vect_dot_prod(TEST_LEN, k, g_tbls, recov, temp_buff);
#else
			gf_vect_dot_prod_base(TEST_LEN, k, &g_tbls[0], recov, temp_buff);
#endif
			if (0 != memcmp(temp_buff, buffs[src_err_list[i]],
						TEST_LEN)){
				printf("Fail error recovery (%d, %d, %d) - ", m, k, nerrs);
				printf(" - erase list = ");
				for (i=0; i<nerrs; i++)
					printf(" %d", src_err_list[i]);
				printf("\na:\n"); 
				dump_u8xu8((u8*)a, m, k);
				printf("inv b:\n");   
				dump_u8xu8((u8*)d, k, k);
				printf("orig data:\n"); 
				dump_matrix(buffs, m, 25);
				printf("orig   :");     
				dump(buffs[src_err_list[i]],25);
				printf("recov %d:",src_err_list[i]); 
				dump(temp_buff, 25);
				return -1;
			}
		}
		putchar('.');
	}

	// Run tests at end of buffer for Electric Fence
	align = (LEN_ALIGN_CHK_B != 0) ? 1 : 16;
	for(size=EFENCE_TEST_MIN_SIZE; size<=TEST_SIZE; size+=align){
		for(i=0; i<TEST_SOURCES; i++)
			for(j=0; j<TEST_LEN; j++)
				buffs[i][j] = rand();

		for(i=0; i<TEST_SOURCES; i++) // Line up TEST_SIZE from end
			efence_buffs[i] = buffs[i] + TEST_LEN - size;

		for (i=0; i<TEST_SOURCES; i++)
			g[i] = rand();

		for(i=0; i<TEST_SOURCES; i++)
			gf_vect_mul_init(g[i], &g_tbls[i*32]);

		gf_vect_dot_prod_base(size, TEST_SOURCES, &g_tbls[0], efence_buffs, dest_ref);
		gf_vect_dot_prod(size, TEST_SOURCES, g_tbls, efence_buffs, dest);

		if (0 != memcmp(dest_ref, dest, size)){
			printf("Fail rand vect_dot_prod test 3\n");
			dump_matrix(efence_buffs, 5, TEST_SOURCES);
			printf("dprod_base:");
			dump(dest_ref, align);
			printf("dprod:");
			dump(dest, align);
			return -1;
		}

		putchar('.');
	}

	// Test rand ptr alignment if available

	for(rtest=0; rtest<RANDOMS; rtest++){
		size = (TEST_LEN - PTR_ALIGN_CHK_B) & ~15;
		srcs = rand() % TEST_SOURCES;
		if (srcs == 0)
			continue;

		offset = (PTR_ALIGN_CHK_B != 0) ? 1 : PTR_ALIGN_CHK_B;
		// Add random offsets
		for(i=0; i<srcs; i++)
			ubuffs[i] = buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));

		udest_ptr = dest + (rand() & (PTR_ALIGN_CHK_B - offset));

		memset(dest, 0, TEST_LEN);  // zero pad to check write-over

		for(i=0; i<srcs; i++)
			for(j=0; j<size; j++)
				ubuffs[i][j] = rand();

		for (i=0; i<srcs; i++)
			g[i] = rand();

		for(i=0; i<srcs; i++)
			gf_vect_mul_init(g[i], &g_tbls[i*32]);

		gf_vect_dot_prod_base(size, srcs, &g_tbls[0], ubuffs, dest_ref);

		gf_vect_dot_prod(size, srcs, g_tbls, ubuffs, udest_ptr);

		if (memcmp(dest_ref, udest_ptr, size)){
			printf("Fail rand vect_dot_prod test ualign srcs=%d\n", srcs);
			dump_matrix(ubuffs, 5, TEST_SOURCES);
			printf("dprod_base:"); 
			dump(dest_ref, 25);
			printf("dprod:"); 
			dump(udest_ptr, 25);
			return -1;
		}

		// Confirm that padding around dests is unchanged
		memset(dest_ref, 0, PTR_ALIGN_CHK_B);  // Make reference zero buff
		offset = udest_ptr - dest;

		if (memcmp(dest, dest_ref, offset)){
			printf("Fail rand ualign pad start\n");
			return -1;
		}
		if (memcmp(dest + offset + size, dest_ref, PTR_ALIGN_CHK_B - offset)){
			printf("Fail rand ualign pad end\n");
			return -1;
		}

		putchar('.');
	}


	// Test all size alignment
	align = (LEN_ALIGN_CHK_B != 0) ? 1 : 16;

	for(size=TEST_LEN; size>15; size-=align){
		srcs = TEST_SOURCES;

		for(i=0; i<srcs; i++)
			for(j=0; j<size; j++)
				buffs[i][j] = rand();

		for (i=0; i<srcs; i++)
			g[i] = rand();

		for(i=0; i<srcs; i++)
			gf_vect_mul_init(g[i], &g_tbls[i*32]);

		gf_vect_dot_prod_base(size, srcs, &g_tbls[0], buffs, dest_ref);

		gf_vect_dot_prod(size, srcs, g_tbls, buffs, dest);

		if (memcmp(dest_ref, dest, size)){
			printf("Fail rand vect_dot_prod test ualign len=%d\n", size);
			dump_matrix(buffs, 5, TEST_SOURCES);
			printf("dprod_base:"); 
			dump(dest_ref, 25);
			printf("dprod:"); 
			dump(dest, 25);
			return -1;
		}
	}

	printf("done all: Pass\n");
	return 0;
}