From 127c10d749fe02ad44419398d7edf21c0083ba45 Mon Sep 17 00:00:00 2001 From: Lam Pham-Sy Date: Fri, 31 Aug 2018 19:06:17 +0200 Subject: [PATCH] Draft --- src/fec_base.h | 34 +++++++++++++++++++++++++++++++--- src/fec_context.h | 2 ++ src/fec_rs_fnt.h | 35 +++++++++++++++++++++++++++++------ src/fec_rs_nf4.h | 1 + src/fft_2n.h | 9 ++++++++- test/ec_driver.cpp | 2 +- test/fec_utest.cpp | 2 +- 7 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/fec_base.h b/src/fec_base.h index 3c14316d..10db44b2 100644 --- a/src/fec_base.h +++ b/src/fec_base.h @@ -141,6 +141,7 @@ class FecCode { std::vector& props, off_t offset){}; virtual void encode( + const DecodeContext& context, vec::Buffers& output, std::vector& props, off_t offset, @@ -498,6 +499,15 @@ void FecCode::encode_packet( vec::Buffers output_char(output_len, buf_size); const std::vector output_mem_char = output_char.get_mem(); + // ids of received fragments, from 0 to codelen-1 + vec::Vector fragments_ids(*(this->gf), n_data); + for (unsigned i = 0; i < n_data; i++) { + fragments_ids.set(i, i); + } + vec::Buffers inter_words(n_data, pkt_size); + std::unique_ptr> context = + init_context_dec(fragments_ids, pkt_size, &inter_words); + reset_stats_enc(); while (true) { @@ -517,7 +527,7 @@ void FecCode::encode_packet( timeval t1 = tick(); uint64_t start = hw_timer(); - encode(output, output_parities_props, offset, words); + encode(*context, output, output_parities_props, offset, words); uint64_t end = hw_timer(); uint64_t t2 = hrtime_usec(t1); @@ -918,7 +928,6 @@ bool FecCode::decode_packet( if (fragment_index == n_data) return true; } - fragments_ids.sort(); vec::Vector avail_parity_ids(*(this->gf), n_data - avail_data_nb); @@ -941,6 +950,8 @@ bool FecCode::decode_packet( if (fragment_index < n_data) return false; } + fragments_ids.sort(); + std::cout << "fragments_ids:"; fragments_ids.dump(); decode_build(); @@ -994,6 +1005,8 @@ bool FecCode::decode_packet( vec::pack( words_mem_char, words_mem_T, n_data, pkt_size, word_size); + std::cout << "received:"; words.dump(); + timeval t1 = tick(); uint64_t start = hw_timer(); decode(*context, output, input_parities_props, offset, words); @@ -1007,6 +1020,8 @@ bool FecCode::decode_packet( vec::unpack( output_mem_T, output_mem_char, output_len, pkt_size, word_size); + std::cout << "decoded:"; output.dump(); + for (unsigned i = 0; i < n_data; i++) { if (output_data_bufs[i] != nullptr) { write_pkt( @@ -1039,11 +1054,18 @@ void FecCode::decode( off_t offset, vec::Buffers& words) { + std::cout << "decode_prepare..\n"; // prepare for decoding decode_prepare(context, props, offset, words); + std::cout << "done. decode_apply..\n"; // Lagrange interpolation decode_apply(context, output, words); + std::cout << "decode_apply done.\n"; + + if (type == FecType::SYSTEMATIC) { + this->fft->fft(output, output); + } } /* Prepare for decoding @@ -1063,8 +1085,14 @@ void FecCode::decode_prepare( T thres = (this->gf->card() - 1); for (unsigned i = 0; i < this->n_data; i++) { - const int frag_id = fragments_ids.get(i); + int frag_id = fragments_ids.get(i); + if (type == FecType::SYSTEMATIC && frag_id < this->n_data) { + continue; + } T* chunk = words.get(i); + if (type == FecType::SYSTEMATIC) { + frag_id -= this->n_data; + } // loop over marked symbols for (auto const& data : props[frag_id].get_map()) { off_t loc_offset = data.first; diff --git a/src/fec_context.h b/src/fec_context.h index 357d399a..f65f1319 100644 --- a/src/fec_context.h +++ b/src/fec_context.h @@ -86,6 +86,7 @@ class DecodeContext { this->max_n_2k = (this->n > this->len_2k) ? this->n : this->len_2k; this->fragments_ids = &fragments_ids; + this->output = output; A = std::unique_ptr>(new vec::Poly(gf, n)); A_fft_2k = @@ -274,6 +275,7 @@ class DecodeContext { public: int vx_zero; + vec::Buffers* output = nullptr; private: unsigned k; diff --git a/src/fec_rs_fnt.h b/src/fec_rs_fnt.h index a45096f8..ac1c2ffe 100644 --- a/src/fec_rs_fnt.h +++ b/src/fec_rs_fnt.h @@ -50,6 +50,11 @@ namespace fec { */ template class RsFnt : public FecCode { + private: + std::unique_ptr> inter_bufs_1; + std::unique_ptr> inter_bufs_2; + std::unique_ptr> inter_vecs; + public: RsFnt( FecType type, @@ -113,11 +118,20 @@ class RsFnt : public FecCode { for (unsigned i = 0; i < this->n; i++) { this->r_powers->set(i, this->gf->exp(this->r, i)); } + + if (this->type == FecType::SYSTEMATIC) { + inter_vecs = std::unique_ptr>( + new vec::Vector(*(this->gf), this->n_data)); + inter_bufs_1 = std::unique_ptr>( + new vec::Buffers(this->n_data, this->pkt_size)); + inter_bufs_2 = std::unique_ptr>( + new vec::Buffers(this->n - this->n_data - this->n_outputs, this->pkt_size)); + } } int get_n_outputs() override { - return this->n; + return (this->type == FecType::SYSTEMATIC) ? this->n_parities : this->n; } /** @@ -146,7 +160,7 @@ class RsFnt : public FecCode { // max_value = 2^x T thres = this->gf->card() - 1; // check for out of range value in output - for (unsigned i = 0; i < this->code_len; i++) { + for (unsigned i = 0; i < this->n_outputs; i++) { if (output.get(i) & thres) { props[i].add(offset, OOR_MARK); output.set(i, 0); @@ -155,12 +169,23 @@ class RsFnt : public FecCode { } void encode( + const DecodeContext& context, vec::Buffers& output, std::vector& props, off_t offset, vec::Buffers& words) override { - this->fft->fft(output, words); + if (this->type == FecType::SYSTEMATIC) { + std::cout << "words"; words.dump(); + this->decode_apply(context, *(context.output), words); + std::cout << "intermediate"; context.output->dump(); + vec::Buffers _tmp(*inter_bufs_1, output); + vec::Buffers _output(_tmp, *inter_bufs_2); + this->fft->fft(_output, *(context.output)); + std::cout << "encoded"; output.dump(); + } else { + this->fft->fft(output, words); + } encode_post_process(output, props, offset); } @@ -172,7 +197,7 @@ class RsFnt : public FecCode { // check for out of range value in output unsigned size = output.get_size(); T thres = (this->gf->card() - 1); - for (unsigned i = 0; i < this->code_len; ++i) { + for (unsigned i = 0; i < this->n_outputs; ++i) { T* chunk = output.get(i); for (unsigned j = 0; j < size; ++j) { if (chunk[j] & thres) { @@ -184,8 +209,6 @@ class RsFnt : public FecCode { void decode_add_data(int fragment_index, int row) override { - // not applicable - assert(false); } void decode_add_parities(int fragment_index, int row) override diff --git a/src/fec_rs_nf4.h b/src/fec_rs_nf4.h index e0cbe953..a03b5a81 100644 --- a/src/fec_rs_nf4.h +++ b/src/fec_rs_nf4.h @@ -262,6 +262,7 @@ class RsNf4 : public FecCode { /********** Encoding & Decoding using Buffers **********/ void encode( + const DecodeContext& context, vec::Buffers& output, std::vector& props, off_t offset, diff --git a/src/fft_2n.h b/src/fft_2n.h index abcd9514..8ea4df71 100644 --- a/src/fft_2n.h +++ b/src/fft_2n.h @@ -319,6 +319,7 @@ void Radix2::fft_inv(vec::Buffers& output, vec::Buffers& input) { const unsigned size = this->pkt_size; const unsigned len = this->n; + const unsigned input_len = input.get_n(); // 1st reversion of elements of output for (unsigned i = 0; i < len; i++) { @@ -328,7 +329,13 @@ void Radix2::fft_inv(vec::Buffers& output, vec::Buffers& input) } // copy input to output - output.copy(input); + unsigned i; + for (i = 0; i < input_len; ++i) { + output.copy(i, input.get(i)); + } + for (; i < len; ++i) { + output.fill(i, 0); + } for (unsigned m = len / 2; m >= 1; m /= 2) { unsigned doubled_m = 2 * m; diff --git a/test/ec_driver.cpp b/test/ec_driver.cpp index 376d84d7..d0fdf025 100644 --- a/test/ec_driver.cpp +++ b/test/ec_driver.cpp @@ -41,7 +41,7 @@ char* prefix = nullptr; void xusage() { std::cerr << std::string("Usage: ") + - "ec [-e rs-gf2n-v|rs-gf2n-c|rs-gf2n-fft|rs-gf2n-fft-add|rs-gfp-fft|rs-fnt|rs-nf4]" + + "ec [-e rs-gf2n-v|rs-gf2n-c|rs-gf2n-fft|rs-gf2n-fft-add|rs-gfp-fft|rs-fnt|rs-fnt-sys|rs-nf4]" + "[-w word_size][-n n_data][-m n_parities][-p prefix][-v (verbose)]" + " -c (encode) | -r (repair)\n"; exit(1); diff --git a/test/fec_utest.cpp b/test/fec_utest.cpp index f99967c8..ae1aee6f 100644 --- a/test/fec_utest.cpp +++ b/test/fec_utest.cpp @@ -85,7 +85,7 @@ class FecTestCommon : public ::testing::Test { } }; -using AllTypes = ::testing::Types; +using AllTypes = ::testing::Types; TYPED_TEST_CASE(FecTestCommon, AllTypes); TYPED_TEST(FecTestCommon, TestNf4) // NOLINT