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; }