/* (**************************************************************************) (* *) (* Schifra *) (* Reed-Solomon Error Correcting Code Library *) (* *) (* Release Version 0.0.1 *) (* http://www.schifra.com *) (* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) (* *) (* The Schifra Reed-Solomon error correcting code library and all its *) (* components are supplied under the terms of the General Schifra License *) (* agreement. The contents of the Schifra Reed-Solomon error correcting *) (* code library and all its components may not be copied or disclosed *) (* except in accordance with the terms of that agreement. *) (* *) (* URL: http://www.schifra.com/license.html *) (* *) (**************************************************************************) */ #ifndef INCLUDE_SCHIFRA_REED_SOLOMON_SPPED_EVALUATOR_HPP #define INCLUDE_SCHIFRA_REED_SOLOMON_SPPED_EVALUATOR_HPP #include #include #include #include #include "schifra_galois_field.hpp" #include "schifra_sequential_root_generator_polynomial_creator.hpp" #include "schifra_reed_solomon_block.hpp" #include "schifra_reed_solomon_encoder.hpp" #include "schifra_reed_solomon_decoder.hpp" #include "schifra_reed_solomon_file_encoder.hpp" #include "schifra_reed_solomon_file_decoder.hpp" #include "schifra_error_processes.hpp" #include "schifra_utilities.hpp" namespace schifra { namespace reed_solomon { template void create_messages(const encoder& rs_encoder, std::vector< block >& original_block_list, const bool full_test_set = false) { const std::size_t data_length = code_length - fec_length; std::vector message_list; if (full_test_set) { for (unsigned int i = 0; i < 256; ++i) { message_list.push_back(std::string(data_length,static_cast(i))); } } else { message_list.push_back(std::string(data_length,static_cast(0x00))); message_list.push_back(std::string(data_length,static_cast(0xAA))); message_list.push_back(std::string(data_length,static_cast(0xA5))); message_list.push_back(std::string(data_length,static_cast(0xAC))); message_list.push_back(std::string(data_length,static_cast(0xCA))); message_list.push_back(std::string(data_length,static_cast(0x5A))); message_list.push_back(std::string(data_length,static_cast(0xCC))); message_list.push_back(std::string(data_length,static_cast(0xF0))); message_list.push_back(std::string(data_length,static_cast(0x0F))); message_list.push_back(std::string(data_length,static_cast(0xFF))); message_list.push_back(std::string(data_length,static_cast(0x92))); message_list.push_back(std::string(data_length,static_cast(0x6D))); message_list.push_back(std::string(data_length,static_cast(0x77))); message_list.push_back(std::string(data_length,static_cast(0x7A))); message_list.push_back(std::string(data_length,static_cast(0xA7))); message_list.push_back(std::string(data_length,static_cast(0xE5))); message_list.push_back(std::string(data_length,static_cast(0xEB))); } std::string tmp_str = std::string(data_length,static_cast(0x00)); for (std::size_t i = 0; i < data_length; ++i) { tmp_str[i] = static_cast(i); } message_list.push_back(tmp_str); for (int i = data_length - 1; i >= 0; --i) { tmp_str[i] = static_cast(i); } message_list.push_back(tmp_str); for (std::size_t i = 0; i < data_length; ++i) { tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); } message_list.push_back(tmp_str); for (std::size_t i = 0; i < data_length; ++i) { tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); } message_list.push_back(tmp_str); for (int i = data_length - 1; i >= 0; --i) { tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); } message_list.push_back(tmp_str); for (int i = data_length - 1; i >= 0; --i) { tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); } message_list.push_back(tmp_str); tmp_str = std::string(data_length,static_cast(0x00)); for (std::size_t i = 0; i < (data_length >> 1); ++i) { tmp_str[i] = static_cast(0xFF); } message_list.push_back(tmp_str); tmp_str = std::string(data_length,static_cast(0xFF)) ; for (std::size_t i = 0; i < (data_length >> 1); ++i) { tmp_str[i] = static_cast(0x00); } message_list.push_back(tmp_str); for (std::size_t i = 0; i < message_list.size(); ++i) { block current_block; rs_encoder.encode(message_list[i],current_block); original_block_list.push_back(current_block); } } template , typename RSDecoder = decoder, std::size_t data_length = code_length - fec_length> struct all_errors_decoder_speed_test { public: all_errors_decoder_speed_test(const std::size_t prim_poly_size, const unsigned int prim_poly[]) { galois::field field(field_descriptor,prim_poly_size,prim_poly); galois::field_polynomial generator_polynomial(field); if ( !make_sequential_root_generator_polynomial(field, gen_poly_index, fec_length, generator_polynomial) ) { return; } RSEncoder rs_encoder(field,generator_polynomial); RSDecoder rs_decoder(field,gen_poly_index); std::vector< block > original_block; create_messages(rs_encoder,original_block); std::vector > rs_block; std::vector block_index_list; for (std::size_t block_index = 0; block_index < original_block.size(); ++block_index) { for (std::size_t error_count = 1; error_count <= (fec_length >> 1); ++error_count) { for (std::size_t start_position = 0; start_position < code_length; ++start_position) { block block = original_block[block_index]; corrupt_message_all_errors(block,error_count,start_position,1); rs_block.push_back(block); block_index_list.push_back(block_index); } } } const std::size_t max_iterations = 100; std::size_t blocks_decoded = 0; std::size_t block_failures = 0; schifra::utils::timer timer; timer.start(); for (std::size_t j = 0; j < max_iterations; ++j) { for (std::size_t i = 0; i < rs_block.size(); ++i) { if (!rs_decoder.decode(rs_block[i])) { std::cout << "Decoding Failure!" << std::endl; block_failures++; } else if (!are_blocks_equivelent(rs_block[i],original_block[block_index_list[i]])) { std::cout << "Error Correcting Failure!" << std::endl; block_failures++; } else blocks_decoded++; } } timer.stop(); double time = timer.time(); double mbps = ((max_iterations * rs_block.size() * data_length) * 8.0) / (1048576.0 * time); print_codec_properties(); if (block_failures == 0) printf("Blocks decoded: %8d Time:%8.3fsec Rate:%8.3fMbps\n", static_cast(blocks_decoded), time, mbps); else std::cout << "Blocks decoded: " << blocks_decoded << "\tDecode Failures: " << block_failures <<"\tTime: " << time <<"sec\tRate: " << mbps << "Mbps" << std::endl; } void print_codec_properties() { printf("[All Errors Test] Codec: RS(%03d,%03d,%03d) ", static_cast(code_length), static_cast(data_length), static_cast(fec_length)); } }; template , typename RSDecoder = decoder, std::size_t data_length = code_length - fec_length> struct all_erasures_decoder_speed_test { public: all_erasures_decoder_speed_test(const std::size_t prim_poly_size, const unsigned int prim_poly[]) { galois::field field(field_descriptor,prim_poly_size,prim_poly); galois::field_polynomial generator_polynomial(field); if ( !make_sequential_root_generator_polynomial(field, gen_poly_index, fec_length, generator_polynomial) ) { return; } RSEncoder rs_encoder(field,generator_polynomial); RSDecoder rs_decoder(field,gen_poly_index); std::vector< block > original_block; create_messages(rs_encoder,original_block); std::vector > rs_block; std::vector erasure_list; std::vector block_index_list; for (std::size_t block_index = 0; block_index < original_block.size(); ++block_index) { for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) { for (std::size_t start_position = 0; start_position < code_length; ++start_position) { block block = original_block[block_index]; erasure_locations_t erasures; corrupt_message_all_erasures(block,erasures,erasure_count,start_position,1); if (erasure_count != erasures.size()) { std::cout << "all_erasures_decoder_speed_test() - Failed to properly generate erasures list. Details:"; std::cout << "(" << block_index << "," << erasure_count << "," << start_position << ")" << std::endl; } rs_block.push_back(block); erasure_list.push_back(erasures); block_index_list.push_back(block_index); } } } const std::size_t max_iterations = 100; std::size_t blocks_decoded = 0; std::size_t block_failures = 0; schifra::utils::timer timer; timer.start(); for (std::size_t j = 0; j < max_iterations; ++j) { for (std::size_t i = 0; i < rs_block.size(); ++i) { if (!rs_decoder.decode(rs_block[i],erasure_list[i])) { std::cout << "Decoding Failure!" << std::endl; block_failures++; } else if (!are_blocks_equivelent(rs_block[i],original_block[block_index_list[i]])) { std::cout << "Error Correcting Failure!" << std::endl; block_failures++; } else blocks_decoded++; } } timer.stop(); double time = timer.time(); double mbps = ((max_iterations * rs_block.size() * data_length) * 8.0) / (1048576.0 * time); print_codec_properties(); if (block_failures == 0) printf("Blocks decoded: %8d Time:%8.3fsec Rate:%8.3fMbps\n", static_cast(blocks_decoded), time, mbps); else std::cout << "Blocks decoded: " << blocks_decoded << "\tDecode Failures: " << block_failures <<"\tTime: " << time <<"sec\tRate: " << mbps << "Mbps" << std::endl; } void print_codec_properties() { printf("[All Erasures Test] Codec: RS(%03d,%03d,%03d) ", static_cast(code_length), static_cast(data_length), static_cast(fec_length)); } }; void speed_test_00() { all_errors_decoder_speed_test<8,120,255, 2>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 4>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 6>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 8>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 12>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 32>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 48>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 64>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 80>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255, 96>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_errors_decoder_speed_test<8,120,255,128>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); } void speed_test_01() { all_erasures_decoder_speed_test<8,120,255, 2>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 4>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 6>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 8>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 12>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 32>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 48>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 64>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 80>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255, 96>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); all_erasures_decoder_speed_test<8,120,255,128>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); } } // namespace reed_solomon } // namespace schifra #endif