commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 05/25: polar: VOLK kernel integration


From: git
Subject: [Commit-gnuradio] [gnuradio] 05/25: polar: VOLK kernel integration
Date: Wed, 23 Sep 2015 14:51:36 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 73d84a231c31bf8312214b5e3a0a97e15c8db98f
Author: Johannes Demel <address@hidden>
Date:   Tue Jul 21 15:47:04 2015 +0200

    polar: VOLK kernel integration
    
    Conflicts:
        volk
---
 gr-fec/examples/polar_ber_curve_gen.grc            |  10 +-
 gr-fec/examples/polar_encoder_decoder_chain.grc    | 115 +++++++++---
 gr-fec/include/gnuradio/fec/polar_decoder_common.h |   4 +-
 gr-fec/include/gnuradio/fec/polar_encoder.h        |  15 +-
 gr-fec/lib/polar_common.cc                         |   7 +-
 gr-fec/lib/polar_decoder_common.cc                 |  60 ++++---
 gr-fec/lib/polar_decoder_sc.cc                     |   4 +-
 gr-fec/lib/polar_decoder_sc_list.cc                |   2 +-
 gr-fec/lib/polar_encoder.cc                        | 102 ++++-------
 gr-fec/python/fec/polar/channel_construction.py    | 194 ++++++++++++++++++++-
 .../python/fec/polar/channel_construction_bsc.py   |   3 +-
 gr-fec/python/fec/polar/helper_functions.py        |  77 ++++++--
 gr-fec/python/fec/polar/testbed.py                 |   4 +-
 gr-fec/python/fec/qa_polar_decoder_sc.py           |  62 +++----
 gr-fec/python/fec/qa_polar_encoder.py              |  73 ++++----
 15 files changed, 507 insertions(+), 225 deletions(-)

diff --git a/gr-fec/examples/polar_ber_curve_gen.grc 
b/gr-fec/examples/polar_ber_curve_gen.grc
index 01fed83..b4e2f87 100644
--- a/gr-fec/examples/polar_ber_curve_gen.grc
+++ b/gr-fec/examples/polar_ber_curve_gen.grc
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='utf-8'?>
-<?grc format='1' created='3.7.8'?>
+<?grc format='1' created='3.7.8rc1'?>
 <flow_graph>
   <timestamp>Fri Jul 17 15:23:09 2015</timestamp>
   <block>
@@ -13,6 +13,10 @@
       <value></value>
     </param>
     <param>
+      <key>window_size</key>
+      <value>1920,1080</value>
+    </param>
+    <param>
       <key>category</key>
       <value>Custom</value>
     </param>
@@ -68,10 +72,6 @@
       <key>title</key>
       <value>polar code BER curve generator</value>
     </param>
-    <param>
-      <key>window_size</key>
-      <value>1920,1080</value>
-    </param>
   </block>
   <block>
     <key>variable</key>
diff --git a/gr-fec/examples/polar_encoder_decoder_chain.grc 
b/gr-fec/examples/polar_encoder_decoder_chain.grc
index 69fb68b..f2501b9 100644
--- a/gr-fec/examples/polar_encoder_decoder_chain.grc
+++ b/gr-fec/examples/polar_encoder_decoder_chain.grc
@@ -13,6 +13,10 @@
       <value></value>
     </param>
     <param>
+      <key>window_size</key>
+      <value>1920, 1080</value>
+    </param>
+    <param>
       <key>category</key>
       <value>Custom</value>
     </param>
@@ -25,10 +29,9 @@
     tb.start()
     tb.wait()
     stop_time = time.time()
-    samps = 2 ** 22
     diff = stop_time - start_time
     throughput = tb.head_samps / diff
-    print("exe time:", diff, ", with ", tb.head_samps, "samps, throughput: ", 
throughput)</value>
+    print("execution time: {0:.6f} for {1:e} samples with throughput: {2:,.2f} 
Sps".format(diff, tb.head_samps, throughput))</value>
     </param>
     <param>
       <key>description</key>
@@ -48,7 +51,7 @@
     </param>
     <param>
       <key>generate_options</key>
-      <value>qt_gui</value>
+      <value>no_gui</value>
     </param>
     <param>
       <key>id</key>
@@ -78,9 +81,32 @@
       <key>title</key>
       <value>POLAR Encoder and Decoder</value>
     </param>
+  </block>
+  <block>
+    <key>variable</key>
     <param>
-      <key>window_size</key>
-      <value>1920, 1080</value>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(704, 35)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>block_size</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>2 ** 11</value>
     </param>
   </block>
   <block>
@@ -107,18 +133,45 @@
     </param>
     <param>
       <key>value</key>
-      <value>2 ** 22</value>
+      <value>2 ** 32# encoder: 32, decoder: 23</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(792, 35)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>n_info_bits</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>block_size / 2</value>
     </param>
   </block>
   <block>
     <key>variable_polar_code_configurator</key>
     <param>
       <key>num_info_bits</key>
-      <value>128</value>
+      <value>n_info_bits</value>
     </param>
     <param>
       <key>block_size</key>
-      <value>256</value>
+      <value>block_size</value>
     </param>
     <param>
       <key>channel</key>
@@ -134,7 +187,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(600, 139)</value>
+      <value>(704, 99)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -146,22 +199,22 @@
     </param>
     <param>
       <key>design_snr</key>
-      <value>2.0</value>
+      <value>-1.0</value>
     </param>
     <param>
       <key>mu</key>
-      <value>16</value>
+      <value>32</value>
     </param>
   </block>
   <block>
     <key>variable_polar_decoder_sc_def</key>
     <param>
       <key>num_info_bits</key>
-      <value>128</value>
+      <value>n_info_bits</value>
     </param>
     <param>
       <key>block_size</key>
-      <value>256</value>
+      <value>block_size</value>
     </param>
     <param>
       <key>comment</key>
@@ -181,11 +234,11 @@
     </param>
     <param>
       <key>frozen_bit_positions</key>
-      <value>range(128)</value>
+      <value>polar_config['positions']</value>
     </param>
     <param>
       <key>frozen_bit_values</key>
-      <value>[0] * 128</value>
+      <value>polar_config['values']</value>
     </param>
     <param>
       <key>_coordinate</key>
@@ -212,11 +265,11 @@
     <key>variable_polar_encoder_def</key>
     <param>
       <key>num_info_bits</key>
-      <value>128</value>
+      <value>n_info_bits</value>
     </param>
     <param>
       <key>block_size</key>
-      <value>256</value>
+      <value>block_size</value>
     </param>
     <param>
       <key>comment</key>
@@ -236,11 +289,11 @@
     </param>
     <param>
       <key>frozen_bit_positions</key>
-      <value>range(128)</value>
+      <value>polar_config['positions']</value>
     </param>
     <param>
       <key>frozen_bit_values</key>
-      <value>[0] * 128</value>
+      <value>polar_config['values']</value>
     </param>
     <param>
       <key>_coordinate</key>
@@ -256,7 +309,7 @@
     </param>
     <param>
       <key>is_packed</key>
-      <value>True</value>
+      <value>False</value>
     </param>
     <param>
       <key>ndim</key>
@@ -267,11 +320,11 @@
     <key>variable_polar_decoder_sc_list_def</key>
     <param>
       <key>num_info_bits</key>
-      <value>128</value>
+      <value>n_info_bits</value>
     </param>
     <param>
       <key>block_size</key>
-      <value>256</value>
+      <value>block_size</value>
     </param>
     <param>
       <key>comment</key>
@@ -401,7 +454,7 @@
     </param>
     <param>
       <key>_enabled</key>
-      <value>True</value>
+      <value>0</value>
     </param>
     <param>
       <key>_coordinate</key>
@@ -495,7 +548,7 @@
     </param>
     <param>
       <key>_enabled</key>
-      <value>True</value>
+      <value>0</value>
     </param>
     <param>
       <key>_coordinate</key>
@@ -601,7 +654,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1160, 464)</value>
+      <value>(1152, 465)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -648,7 +701,7 @@
     </param>
     <param>
       <key>_enabled</key>
-      <value>True</value>
+      <value>0</value>
     </param>
     <param>
       <key>_coordinate</key>
@@ -699,7 +752,7 @@
     </param>
     <param>
       <key>_enabled</key>
-      <value>False</value>
+      <value>1</value>
     </param>
     <param>
       <key>encoder_list</key>
@@ -750,7 +803,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(968, 32)</value>
+      <value>(1208, 19)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -1178,4 +1231,10 @@
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
+  <connection>
+    <source_block_id>fec_extended_encoder_0</source_block_id>
+    <sink_block_id>blocks_head_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
 </flow_graph>
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_common.h 
b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
index 50003b6..61a6564 100644
--- a/gr-fec/include/gnuradio/fec/polar_decoder_common.h
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
@@ -60,7 +60,9 @@ namespace gr {
       // preparation for decoding
       void initialize_llr_vector(float* llrs, const float* input);
       // basic algorithm methods
-      void butterfly(float* llrs, const int stage, unsigned char* u, const int 
u_num);
+      void butterfly(float* llrs, unsigned char* u, const int stage, const int 
u_num, const int row);
+      void butterfly_volk(float* llrs, unsigned char* u, const int stage, 
const int u_num, const int row);
+      void butterfly_generic(float* llrs, unsigned char* u, const int stage, 
const int u_num, const int row);
       void even_u_values(unsigned char* u_even, const unsigned char* u, const 
int u_num);
       void odd_xor_even_values(unsigned char* u_xor, const unsigned char* u, 
const int u_num);
       void demortonize_values(unsigned char* u);
diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h 
b/gr-fec/include/gnuradio/fec/polar_encoder.h
index 85208bf..20ff5dc 100644
--- a/gr-fec/include/gnuradio/fec/polar_encoder.h
+++ b/gr-fec/include/gnuradio/fec/polar_encoder.h
@@ -51,23 +51,17 @@ namespace gr {
       const char* get_output_conversion(){return is_packed() ? "packed_bits" : 
"none";};
 
     private:
-      polar_encoder(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+      polar_encoder(int block_size, int num_info_bits, std::vector<int>& 
frozen_bit_positions, std::vector<char>& frozen_bit_values, bool is_packed);
       std::vector<int> d_frozen_bit_positions;
       std::vector<int> d_info_bit_positions;
       std::vector<char> d_frozen_bit_values;
 
-      // for unpacked bits an 'easier-to-grasp' algorithm.
-      void insert_frozen_bits(unsigned char* target, const unsigned char* 
input);
-      void bit_reverse_vector(unsigned char* target, const unsigned char* 
input);
-      void encode_vector(unsigned char* target);
-
       // c'tor method for packed algorithm setup.
       void setup_frozen_bit_inserter();
 
       // methods insert input bits and frozen bits into packed array for 
encoding
       unsigned char* d_block_array; // use for encoding
       unsigned char* d_frozen_bit_prototype; // packed frozen bits are written 
onto it and later copies are used.
-      void insert_unpacked_frozen_bits_and_reverse(unsigned char* target, 
const unsigned char* input) const;
       void insert_packed_frozen_bits_and_reverse(unsigned char* target, const 
unsigned char* input) const;
       void insert_unpacked_bit_into_packed_array_at_position(unsigned char* 
target, const unsigned char bit, const int pos) const;
       void insert_packet_bit_into_packed_array_at_position(unsigned char* 
target, const unsigned char bit, const int target_pos, const int bit_pos) const;
@@ -78,8 +72,13 @@ namespace gr {
       void encode_packed_byte(unsigned char* target) const;
       void encode_vector_packed_interbyte(unsigned char* target) const;
 
+      // VOLK methods
+      void setup_volk_vectors();
+      void volk_encode(unsigned char* out_buf, const unsigned char* in_buf);
+      unsigned char* d_temp;
+      unsigned char* d_frozen_bit_mask;
+      unsigned char* d_frozen_bits;
     };
-
   } // namespace fec
 } // namespace gr
 
diff --git a/gr-fec/lib/polar_common.cc b/gr-fec/lib/polar_common.cc
index c76f530..19caedf 100644
--- a/gr-fec/lib/polar_common.cc
+++ b/gr-fec/lib/polar_common.cc
@@ -77,16 +77,21 @@ namespace gr
     polar_common::initialize_info_bit_position_vector()
     {
       int num_frozen_bit = 0;
+      int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
       for(int i = 0; i < block_size(); i++) {
-        int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
         if(i != frozen_pos) {
           d_info_bit_positions.push_back((int) i);
         }
         else {
           num_frozen_bit++;
           num_frozen_bit = std::min(num_frozen_bit, (int) 
(d_frozen_bit_positions.size() - 1));
+          frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
         }
       }
+
+      if((int) d_info_bit_positions.size() != num_info_bits()) {
+        throw std::runtime_error("polar_common: number of info bit positions 
MUST equal num_info_bits (K)!");
+      }
     }
 
     polar_common::~polar_common()
diff --git a/gr-fec/lib/polar_decoder_common.cc 
b/gr-fec/lib/polar_decoder_common.cc
index bcb70fc..2263795 100644
--- a/gr-fec/lib/polar_decoder_common.cc
+++ b/gr-fec/lib/polar_decoder_common.cc
@@ -30,8 +30,6 @@
 
 #include <cstdio>
 
-#define INT_BIT_MASK 0x80000000
-
 namespace gr {
   namespace fec {
 
@@ -73,40 +71,60 @@ namespace gr {
     }
 
     void
-    polar_decoder_common::butterfly(float* llrs, const int stage, unsigned 
char* u, const int u_num)
+    polar_decoder_common::butterfly(float* llrs, unsigned char* u, const int 
stage, const int u_num,
+                                    const int row)
+    {
+      butterfly_volk(llrs, u, stage, u_num, row);
+    }
+
+    void
+    polar_decoder_common::butterfly_generic(float* llrs, unsigned char* u, 
const int stage,
+                                            const int u_num, const int row)
     {
-//      if(!(block_power() > stage)){
-//        return;
-//      }
       const int next_stage = stage + 1;
-      const int stage_half_block_size = block_size() >> next_stage;
-
-//      // this is a natural bit order impl
-      float* next_llrs = llrs + block_size(); // LLRs are stored in an 
consecutive array.
-      float* call_row_llr = llrs + u_num;
-      const int upper_right = u_num >> 1; // floor divide by 2.
-      const float* upper_right_llr_ptr = next_llrs + upper_right;
-      const float* lower_right_llr_ptr = upper_right_llr_ptr + 
stage_half_block_size;
-
-      if(u_num % 2){
-        const unsigned char f = u[u_num - 1];
-//        const unsigned char f = fetch_bit_at_pos(u, u_num - 1);
+      const int half_stage_size = 0x01 << stage;
+      const int stage_size = half_stage_size << 1;
+      const bool is_upper_stage_half = row % stage_size < half_stage_size;
+
+      //      // this is a natural bit order impl
+      float* next_llrs = llrs + block_size(); // LLRs are stored in a 
consecutive array.
+      float* call_row_llr = llrs + row;
+
+      const int section = row - (row % stage_size);
+      const int jump_size = ((row % half_stage_size) << 1) % stage_size;
+
+      const int next_upper_row = section + jump_size;
+      const int next_lower_row = next_upper_row + 1;
+
+      const float* upper_right_llr_ptr = next_llrs + next_upper_row;
+      const float* lower_right_llr_ptr = next_llrs + next_lower_row;
+
+      if(!is_upper_stage_half){
+        const int u_pos = u_num >> stage;
+        const unsigned char f = u[u_pos - 1];
         *call_row_llr = llr_even(*upper_right_llr_ptr, *lower_right_llr_ptr, 
f);
         return;
       }
 
-      if(block_power() > next_stage) {
+      if(block_power() > next_stage){
         unsigned char* u_half = u + block_size();
         odd_xor_even_values(u_half, u, u_num);
-        butterfly(next_llrs, next_stage, u_half, upper_right);
+        butterfly(next_llrs, u_half, next_stage, u_num, next_upper_row);
 
         even_u_values(u_half, u, u_num);
-        butterfly(next_llrs + stage_half_block_size, next_stage, u_half, 
upper_right);
+        butterfly(next_llrs, u_half, next_stage, u_num, next_lower_row);
       }
 
       *call_row_llr = llr_odd(*upper_right_llr_ptr, *lower_right_llr_ptr);
     }
 
+    void
+    polar_decoder_common::butterfly_volk(float* llrs, unsigned char* u, const 
int stage,
+                                         const int u_num, const int row)
+    {
+      volk_32f_8u_polarbutterfly_32f(llrs, u, block_size(), block_power(), 
stage, u_num, row);
+    }
+
 
     void
     polar_decoder_common::even_u_values(unsigned char* u_even, const unsigned 
char* u,
diff --git a/gr-fec/lib/polar_decoder_sc.cc b/gr-fec/lib/polar_decoder_sc.cc
index e4f64b5..7a290a8 100644
--- a/gr-fec/lib/polar_decoder_sc.cc
+++ b/gr-fec/lib/polar_decoder_sc.cc
@@ -80,10 +80,8 @@ namespace gr
       d_frozen_bit_counter = 0;
       memset(u, 0, sizeof(unsigned char) * block_size() * block_power());
       for(int i = 0; i < block_size(); i++){
-        butterfly(llrs, 0, u, i);
+        butterfly(llrs, u, 0, i, i);
         u[i] = retrieve_bit_from_llr(llrs[i], i);
-//        const unsigned char bit = retrieve_bit_from_llr(llrs[i], i);
-//        insert_bit_at_pos(u, bit, i);
       }
     }
 
diff --git a/gr-fec/lib/polar_decoder_sc_list.cc 
b/gr-fec/lib/polar_decoder_sc_list.cc
index 9340e30..67b20f2 100644
--- a/gr-fec/lib/polar_decoder_sc_list.cc
+++ b/gr-fec/lib/polar_decoder_sc_list.cc
@@ -115,7 +115,7 @@ namespace gr
     void
     polar_decoder_sc_list::calculate_next_llr(polar::path* current_path, int 
u_num)
     {
-      butterfly(current_path->llr_vec, 0, current_path->u_vec, u_num);
+      butterfly(current_path->llr_vec, current_path->u_vec, 0, u_num, u_num);
     }
   } /* namespace fec */
 } /* namespace gr */
diff --git a/gr-fec/lib/polar_encoder.cc b/gr-fec/lib/polar_encoder.cc
index 7187ea6..40ffb05 100644
--- a/gr-fec/lib/polar_encoder.cc
+++ b/gr-fec/lib/polar_encoder.cc
@@ -48,8 +48,8 @@ namespace gr
     }
 
     polar_encoder::polar_encoder(int block_size, int num_info_bits,
-                                 std::vector<int> frozen_bit_positions,
-                                 std::vector<char> frozen_bit_values, bool 
is_packed) :
+                                 std::vector<int>& frozen_bit_positions,
+                                 std::vector<char>& frozen_bit_values, bool 
is_packed) :
         polar_common(block_size, num_info_bits, frozen_bit_positions, 
frozen_bit_values, is_packed),
             d_frozen_bit_positions(frozen_bit_positions),
             d_frozen_bit_values(frozen_bit_values)
@@ -61,6 +61,7 @@ namespace gr
       }
 
       setup_frozen_bit_inserter();
+      setup_volk_vectors();
     }
 
     void
@@ -84,7 +85,29 @@ namespace gr
       }
 
       if((int) d_info_bit_positions.size() != num_info_bits()) {
-        throw std::runtime_error("number of info bit positions MUST equal 
num_info_bits (K)!");
+        throw std::runtime_error("polar_encoder: number of info bit positions 
MUST equal num_info_bits (K)!");
+      }
+    }
+
+    void
+    polar_encoder::setup_volk_vectors()
+    {
+      int nfrozen = block_size() - num_info_bits();
+      d_temp = (unsigned char*) volk_malloc(sizeof(unsigned char) * 
block_size(), volk_get_alignment());
+      d_frozen_bit_mask = (unsigned char*) volk_malloc(sizeof(unsigned char) * 
block_size(), volk_get_alignment());
+      d_frozen_bits = (unsigned char*) volk_malloc(sizeof(unsigned char) * 
nfrozen, volk_get_alignment());
+      for(int i = 0; i < nfrozen; i++){
+        d_frozen_bits[i] = d_frozen_bit_values[i];
+      }
+
+      int nfbit = 0;
+      for(int i = 0; i < block_size(); i++){
+        unsigned char m = 0x00;
+        if(d_frozen_bit_positions[nfbit] == i){
+          m = 0xFF;
+          nfbit++;
+        }
+        d_frozen_bit_mask[i] = m;
       }
     }
 
@@ -92,6 +115,10 @@ namespace gr
     {
       volk_free(d_block_array);
       volk_free(d_frozen_bit_prototype);
+
+      volk_free(d_temp);
+      volk_free(d_frozen_bit_mask);
+      volk_free(d_frozen_bits);
     }
 
     void
@@ -105,14 +132,14 @@ namespace gr
         encode_vector_packed(out);
       }
       else {
-        insert_unpacked_frozen_bits_and_reverse(d_block_array, in);
-        encode_vector_packed(d_block_array);
-        unpacker()->unpack(out, d_block_array, block_size() >> 3);
+        volk_encode(out, in);
       }
+    }
 
-//      insert_frozen_bits(d_block_array, in);
-//      bit_reverse_vector(out, d_block_array);
-//      encode_vector(out);
+    void
+    polar_encoder::volk_encode(unsigned char* out_buf, const unsigned char* 
in_buf)
+    {
+      volk_8u_x3_encodepolar_8u_x2(out_buf, d_temp, d_frozen_bit_mask, 
d_frozen_bits, in_buf, block_size());
     }
 
     void
@@ -171,20 +198,6 @@ namespace gr
     }
 
     void
-    polar_encoder::insert_unpacked_frozen_bits_and_reverse(unsigned char* 
target,
-                                                           const unsigned 
char* input) const
-    {
-      memcpy(target, d_frozen_bit_prototype, block_size() >> 3);
-      const int* info_bit_positions_ptr = &d_info_bit_positions[0];
-      const unsigned char* end_input = input + num_info_bits();
-      int bit_pos = 7;
-      while(input < end_input) {
-        insert_packet_bit_into_packed_array_at_position(target, *input++, 
*info_bit_positions_ptr++,
-                                                        bit_pos);
-      }
-    }
-
-    void
     polar_encoder::insert_packed_frozen_bits_and_reverse(unsigned char* target,
                                                          const unsigned char* 
input) const
     {
@@ -223,48 +236,5 @@ namespace gr
       insert_unpacked_bit_into_packed_array_at_position(target, (bit >> (7 - 
bit_pos)) & 0x01,
                                                         target_pos);
     }
-
-    void
-    polar_encoder::insert_frozen_bits(unsigned char* target, const unsigned 
char* input)
-    {
-      int frozen_num = 0;
-      int num_frozen_bits = block_size() - num_info_bits();
-      int info_num = 0;
-      for(int i = 0; i < block_size(); i++) {
-        if(frozen_num < num_frozen_bits && 
d_frozen_bit_positions.at(frozen_num) == i) {
-          target[i] = d_frozen_bit_values.at(frozen_num);
-          frozen_num++;
-        }
-        else {
-          target[i] = input[info_num];
-          info_num++;
-        }
-      }
-    }
-
-    void
-    polar_encoder::bit_reverse_vector(unsigned char* target, const unsigned 
char* input)
-    {
-      for(int i = 0; i < block_size(); i++) {
-        target[bit_reverse(long(i), block_power())] = input[i];
-      }
-    }
-
-    void
-    polar_encoder::encode_vector(unsigned char* target)
-    {
-      for(int stage = 0; stage < block_power(); stage++) {
-        int n_branches = pow(2, stage);
-        int branch_elements = block_size() / (2 * n_branches);
-        for(int branch = 0; branch < n_branches; branch++) {
-          for(int e = 0; e < branch_elements; e++) {
-            int pos = branch * branch_elements * 2 + e;
-            target[pos] ^= target[pos + branch_elements];
-          }
-        }
-      }
-    }
-
   } /* namespace fec */
 } /* namespace gr */
-
diff --git a/gr-fec/python/fec/polar/channel_construction.py 
b/gr-fec/python/fec/polar/channel_construction.py
index f971ce4..9c38d3a 100644
--- a/gr-fec/python/fec/polar/channel_construction.py
+++ b/gr-fec/python/fec/polar/channel_construction.py
@@ -28,6 +28,7 @@ import numpy as np
 from channel_construction_bec import calculate_bec_channel_capacities
 from channel_construction_bec import design_snr_to_bec_eta
 from channel_construction_bsc import tal_vardy_tpm_algorithm
+from helper_functions import *
 import matplotlib.pyplot as plt
 
 
@@ -39,7 +40,7 @@ def get_frozen_bit_indices_from_capacities(chan_caps, 
nfrozen):
     while indexes.size < nfrozen:
         index = np.argmin(chan_caps)
         indexes = np.append(indexes, index)
-        chan_caps[index] = 1.0
+        chan_caps[index] = 2.0  # make absolutely sure value is out of range!
     return np.sort(indexes)
 
 
@@ -109,19 +110,200 @@ def load_z_parameters(block_size, design_snr, mu):
     return z_params
 
 
+def prepare_merger(frozen_mask):
+    mask = []
+    for e in frozen_mask:
+        mask.append([e, ])
+    return np.array(mask, dtype=int)
+
+
+def merge_first_stage(init_mask):
+    merged_frozen_mask = []
+    for e in range(0, len(init_mask), 2):
+        v = [init_mask[e]['value'][0], init_mask[e + 1]['value'][0]]
+        s = init_mask[e]['size'] * 2
+        if init_mask[e]['type'] == init_mask[e + 1]['type']:
+            t = init_mask[e]['type']
+            merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+        else:
+            t = 'RPT'
+            merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+    return merged_frozen_mask
+
+
+def merge_second_stage(init_mask):
+    merged_frozen_mask = []
+    for e in range(0, len(init_mask), 2):
+        if init_mask[e]['type'] == init_mask[e + 1]['type']:
+            t = init_mask[e]['type']
+            v = init_mask[e]['value']
+            v.extend(init_mask[e + 1]['value'])
+            s = init_mask[e]['size'] * 2
+            merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+        elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] == 
'RPT':
+            t = init_mask[e + 1]['type']
+            v = init_mask[e]['value']
+            v.extend(init_mask[e + 1]['value'])
+            s = init_mask[e]['size'] * 2
+            merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+        elif init_mask[e]['type'] == 'RPT' and init_mask[e + 1]['type'] == 
'ONE':
+            t = 'SPC'
+            v = init_mask[e]['value']
+            v.extend(init_mask[e + 1]['value'])
+            s = init_mask[e]['size'] * 2
+            merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+        else:
+            merged_frozen_mask.append(init_mask[e])
+            merged_frozen_mask.append(init_mask[e + 1])
+    return merged_frozen_mask
+
+
+def merge_stage_n(init_mask):
+    merged_frozen_mask = []
+    n_elems = len(init_mask) - (len(init_mask) % 2)
+    for e in range(0, n_elems, 2):
+        if init_mask[e]['size'] == init_mask[e + 1]['size']:
+            if (init_mask[e]['type'] == 'ZERO' or init_mask[e]['type'] == 
'ONE') and init_mask[e]['type'] == init_mask[e + 1]['type']:
+                t = init_mask[e]['type']
+                v = init_mask[e]['value']
+                v.extend(init_mask[e + 1]['value'])
+                s = init_mask[e]['size'] * 2
+                merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+            elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] 
== 'RPT':
+                t = init_mask[e + 1]['type']
+                v = init_mask[e]['value']
+                v.extend(init_mask[e + 1]['value'])
+                s = init_mask[e]['size'] * 2
+                merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+            elif init_mask[e]['type'] == 'SPC' and init_mask[e + 1]['type'] == 
'ONE':
+                t = init_mask[e]['type']
+                v = init_mask[e]['value']
+                v.extend(init_mask[e + 1]['value'])
+                s = init_mask[e]['size'] * 2
+                merged_frozen_mask.append({'value': v, 'type': t, 'size': s})
+            else:
+                merged_frozen_mask.append(init_mask[e])
+                merged_frozen_mask.append(init_mask[e + 1])
+        else:
+            merged_frozen_mask.append(init_mask[e])
+            merged_frozen_mask.append(init_mask[e + 1])
+    if n_elems < len(init_mask):
+        merged_frozen_mask.append(init_mask[-1])
+    return merged_frozen_mask
+
+
+def print_decode_subframes(subframes):
+    for e in subframes:
+        print(e)
+
+
+def find_decoder_subframes(frozen_mask):
+    stages = power_of_2_int(len(frozen_mask))
+    frame_size = 2 ** stages
+
+    lock_mask = np.zeros(frame_size, dtype=int)
+    sub_mask = []
+
+    for e in frozen_mask:
+        if e == 1:
+            sub_mask.append(0)
+        else:
+            sub_mask.append(1)
+    sub_mask = np.array(sub_mask, dtype=int)
+
+    for s in range(0, stages):
+        stage_size = 2 ** s
+        mask = np.reshape(sub_mask, (-1, stage_size))
+        lock = np.reshape(lock_mask, (-1, stage_size))
+        for p in range(0, (frame_size // stage_size) - 1, 2):
+            l0 = lock[p]
+            l1 = lock[p + 1]
+            first = mask[p]
+            second = mask[p + 1]
+            print(l0, l1)
+            print(first, second)
+            if np.all(l0 == l1):
+                for eq in range(2):
+                    if np.all(first == eq) and np.all(second == eq):
+                        mask[p].fill(eq)
+                        mask[p + 1].fill(eq)
+                        lock[p].fill(s)
+                        lock[p + 1].fill(s)
+
+                if np.all(first == 0) and np.all(second == 2):
+                    mask[p].fill(2)
+                    mask[p + 1].fill(2)
+                    lock[p].fill(s)
+                    lock[p + 1].fill(s)
+
+                if np.all(first == 3) and np.all(second == 1):
+                    mask[p].fill(3)
+                    mask[p + 1].fill(3)
+                    lock[p].fill(s)
+                    lock[p + 1].fill(s)
+
+            if s == 0 and np.all(first == 0) and np.all(second == 1):
+                mask[p].fill(2)
+                mask[p + 1].fill(2)
+                lock[p].fill(s)
+                lock[p + 1].fill(s)
+
+            if s == 1 and np.all(first == 2) and np.all(second == 1):
+                mask[p].fill(3)
+                mask[p + 1].fill(3)
+                lock[p].fill(s)
+                lock[p + 1].fill(s)
+
+        sub_mask = mask.flatten()
+        lock_mask = lock.flatten()
+
+    words = {0: 'ZERO', 1: 'ONE', 2: 'RPT', 3: 'SPC'}
+    ll = lock_mask[0]
+    sub_t = sub_mask[0]
+    for i in range(len(frozen_mask)):
+        v = frozen_mask[i]
+        t = words[sub_mask[i]]
+        l = lock_mask[i]
+        # if i % 8 == 0:
+        #     print
+        if not l == ll or not sub_mask[i] == sub_t:
+            print('--------------------------')
+        ll = l
+        sub_t = sub_mask[i]
+        print('{0:4} lock {1:4} value: {2} in sub {3}'.format(i, 2 ** (l + 1), 
v, t))
+
+
+
 def main():
+    np.set_printoptions(precision=3, linewidth=150)
     print 'channel construction Bhattacharyya bounds by Arikan'
-    n = 8
+    n = 10
     m = 2 ** n
     k = m // 2
     design_snr = -1.59
     mu = 32
 
-    # ztv = tal_vardy_tpm_algorithm(m, design_snr, mu)
-
     z_params = load_z_parameters(m, design_snr, mu)
-    plt.plot(z_params)
-    plt.show()
+    # plt.plot(z_params)
+    # plt.show()
+    frozen_indices = get_frozen_bit_indices_from_z_parameters(z_params, k)
+
+    frozen_mask = np.zeros(m, dtype=int)
+    frozen_mask[frozen_indices] = 1
+    # frozen_mask = np.reshape(frozen_mask, (-1, 32))
+    # for p in frozen_mask:
+    #     print(p)
+    #     if np.all(p == 1):
+    #         print("zero rate")
+    #     elif np.all(p == 0):
+    #         print("ONE rate")
+    #     elif p[0] == 1 and np.all(p[1:] == 0):
+    #         print("SPC code")
+    #     elif np.all(p[0:-1] == 1) and p[-1] == 0:
+    #         print("REPETITION code")
+
+    find_decoder_subframes(frozen_mask)
+
 
 
 
diff --git a/gr-fec/python/fec/polar/channel_construction_bsc.py 
b/gr-fec/python/fec/polar/channel_construction_bsc.py
index fddad2e..69acea8 100755
--- a/gr-fec/python/fec/polar/channel_construction_bsc.py
+++ b/gr-fec/python/fec/polar/channel_construction_bsc.py
@@ -315,7 +315,7 @@ def normalize_q(q, tpm):
 
 def main():
     print 'channel construction BSC main'
-    n = 8
+    n = 10
     m = 2 ** n
     k = m // 2
     design_snr = 0.5
@@ -323,6 +323,7 @@ def main():
 
 
     z_params = tal_vardy_tpm_algorithm(m, design_snr, mu)
+    print(z_params)
     plt.plot(z_params)
     plt.show()
 
diff --git a/gr-fec/python/fec/polar/helper_functions.py 
b/gr-fec/python/fec/polar/helper_functions.py
index e93fa9a..72501be 100644
--- a/gr-fec/python/fec/polar/helper_functions.py
+++ b/gr-fec/python/fec/polar/helper_functions.py
@@ -20,6 +20,7 @@
 
 import numpy as np
 import time, sys
+import copy
 
 
 def power_of_2_int(num):
@@ -119,24 +120,72 @@ def main():
 
     for i in range(8):
         print(i, 'is power of 2: ', is_power_of_two(i))
-    n = 2 ** 6
-    k = n // 2
+    n = 6
+    m = 2 ** n
+    k = m // 2
     eta = 0.3
 
-    # frozen_bit_positions = get_frozen_bit_positions('.', 256, 128, 0.11)
-    # print(frozen_bit_positions)
+    pos = np.arange(m)
+    rev_pos = bit_reverse_vector(pos, n)
+    print(pos)
+    print(rev_pos)
+
+    bound = 16
+    num_lanes = m // bound
+
+
+    lanes = np.zeros((num_lanes, bound), dtype=int)
+    for i in range(0, num_lanes):
+        p = i * bound
+        part = rev_pos[p: p + bound]
+        lanes[i] = part
+
+    print('reved lanes')
+    print(lanes)
+
+    # SHUFFLE!
+    shuffle_pos = bit_reverse_vector(np.arange(bound), 4)
+    for i in range(num_lanes):
+        lane = lanes[i]
+        lanes[i] = lanes[i, shuffle_pos]
+    print('\nshuffled lanes')
+    print(lanes)
+
+    # SORT HALVES
+    hb = bound // 2
+    for i in range(num_lanes // 2):
+        l0 = lanes[i]
+        l1 = lanes[i + (num_lanes // 2)]
+        l0p = copy.deepcopy(l0[hb:])
+        l0[hb:] = l1[0:hb]
+        l1[0:hb] = l0p
+        lanes[i] =l0
+        lanes[i + (num_lanes // 2)] = l1
+    print('\nsort halves')
+    print(lanes)
+
+    # 'MELT' SHUFFLE     INTERLEAVE!
+    melt_pos = np.arange(bound, dtype=int)
+    melt_pos = np.reshape(melt_pos, (2, -1)).T.flatten()
+    for i in range(num_lanes):
+        lanes[i] = lanes[i, melt_pos]
+    print('\nmelt lanes')
+    print(lanes)
+
+
+
+    for i in range(0, m, bound):
+        print("\nlook at this part")
+        part = pos[i: i + bound]
+        rev = bit_reverse_vector(part, n)
+        sorted_rev = np.sort(rev)
+        print(part)
+        print(rev)
+        print(sorted_rev)
+        sorted_part = rev[shuffle_pos]
+        print(sorted_part)
 
-    print(np.arange(16))
-    print bit_reverse_vector(np.arange(16), 4)
 
-    ntotal = 99
-    for i in range(ntotal):
-        show_progress_bar(i, ntotal)
-        time.sleep(0.1)
-
-    # sys.stdout.write('Hello')
-    # time.sleep(1)
-    # sys.stdout.write('\rMomy   ')
 
 if __name__ == '__main__':
     main()
diff --git a/gr-fec/python/fec/polar/testbed.py 
b/gr-fec/python/fec/polar/testbed.py
index bdf9ae4..c35b620 100755
--- a/gr-fec/python/fec/polar/testbed.py
+++ b/gr-fec/python/fec/polar/testbed.py
@@ -153,11 +153,11 @@ def main():
     # frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int)
     # print frozenbitposition
 
-    # test_enc_dec_chain()
+    test_enc_dec_chain()
 
     # test_1024_rate_1_code()
 
-    channel_analysis()
+    # channel_analysis()
 
 
 if __name__ == '__main__':
diff --git a/gr-fec/python/fec/qa_polar_decoder_sc.py 
b/gr-fec/python/fec/qa_polar_decoder_sc.py
index 966a9f1..1e7cd25 100644
--- a/gr-fec/python/fec/qa_polar_decoder_sc.py
+++ b/gr-fec/python/fec/qa_polar_decoder_sc.py
@@ -32,7 +32,7 @@ from extended_decoder import extended_decoder
 from polar.encoder import PolarEncoder
 from polar.decoder import PolarDecoder
 import polar.channel_construction as cc
-# from polar.helper_functions import bit_reverse_vector
+from polar.helper_functions import bit_reverse_vector
 
 # print('PID:', os.getpid())
 # raw_input('tell me smth')
@@ -62,22 +62,14 @@ class test_polar_decoder_sc(gr_unittest.TestCase):
     def test_002_one_vector(self):
         print "test_002_one_vector"
         is_packed = False
-        block_power = 8
+        block_power = 10
         block_size = 2 ** block_power
         num_info_bits = 2 ** (block_power - 1)
         num_frozen_bits = block_size - num_info_bits
         frozen_bit_positions = cc.frozen_bit_positions(block_size, 
num_info_bits, 0.0)
         frozen_bit_values = np.array([0] * num_frozen_bits,)
-        print frozen_bit_positions
-
-        python_decoder = PolarDecoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
 
-        bits = np.ones(num_info_bits, dtype=int)
-        # bits = np.random.randint(2, size=num_info_bits)
-        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
-        data = encoder.encode(bits)
-        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
-        gr_data = 2.0 * data - 1.0
+        bits, gr_data = self.generate_test_data(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, 1, True)
 
         polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
         src = blocks.vector_source_f(gr_data, False)
@@ -90,16 +82,14 @@ class test_polar_decoder_sc(gr_unittest.TestCase):
 
         res = np.array(snk.data()).astype(dtype=int)
 
-        ref = python_decoder.decode(data)
-
-        print("input:", data)
+        print("input:", gr_data.astype(dtype=int))
+        print("ref  :", bits)
         print("res  :", res)
-        print("ref  :", ref)
 
-        self.assertTupleEqual(tuple(res), tuple(ref))
+        self.assertTupleEqual(tuple(res), tuple(bits))
 
     def test_003_stream(self):
-        print "test_002_stream"
+        print "test_003_stream"
         nframes = 3
         is_packed = False
         block_power = 8
@@ -108,23 +98,8 @@ class test_polar_decoder_sc(gr_unittest.TestCase):
         num_frozen_bits = block_size - num_info_bits
         frozen_bit_positions = cc.frozen_bit_positions(block_size, 
num_info_bits, 0.0)
         frozen_bit_values = np.array([0] * num_frozen_bits,)
-        print frozen_bit_positions
 
-        python_decoder = PolarDecoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
-        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
-
-        bits = np.array([], dtype=int)
-        data = np.array([], dtype=int)
-        for n in range(nframes):
-            b = np.random.randint(2, size=num_info_bits)
-            d = encoder.encode(b)
-            bits = np.append(bits, b)
-            data = np.append(data, d)
-        # bits = np.ones(num_info_bits, dtype=int)
-        # bits = np.random.randint(2, size=num_info_bits)
-        # data = encoder.encode(bits)
-        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
-        gr_data = 2.0 * data - 1.0
+        bits, gr_data = self.generate_test_data(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, nframes, False)
 
         polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
         src = blocks.vector_source_f(gr_data, False)
@@ -137,14 +112,27 @@ class test_polar_decoder_sc(gr_unittest.TestCase):
 
         res = np.array(snk.data()).astype(dtype=int)
 
-        # ref = python_decoder.decode(data)
-
-        print("input:", data)
+        print("input:", gr_data.astype(dtype=int))
+        print("ref  :", bits)
         print("res  :", res)
-        # print("ref  :", ref)
 
         self.assertTupleEqual(tuple(res), tuple(bits))
 
+    def generate_test_data(self, block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, nframes, onlyones):
+        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+        bits = np.array([], dtype=int)
+        data = np.array([], dtype=int)
+        for n in range(nframes):
+            if onlyones:
+                b = np.ones(num_info_bits, dtype=int)
+            else:
+                b = np.random.randint(2, size=num_info_bits)
+            d = encoder.encode(b)
+            bits = np.append(bits, b)
+            data = np.append(data, d)
+        gr_data = 2.0 * data - 1.0
+        return bits, gr_data
+
 
 if __name__ == '__main__':
     gr_unittest.run(test_polar_decoder_sc)
diff --git a/gr-fec/python/fec/qa_polar_encoder.py 
b/gr-fec/python/fec/qa_polar_encoder.py
index b4f26e4..90190cd 100644
--- a/gr-fec/python/fec/qa_polar_encoder.py
+++ b/gr-fec/python/fec/qa_polar_encoder.py
@@ -28,6 +28,10 @@ from extended_encoder import extended_encoder
 from polar.encoder import PolarEncoder
 import polar.channel_construction as cc
 
+# import os
+# print('PID:', os.getpid())
+# raw_input('tell me smth')
+
 
 class test_polar_encoder(gr_unittest.TestCase):
 
@@ -50,54 +54,45 @@ class test_polar_encoder(gr_unittest.TestCase):
         self.assertFloatTuplesAlmostEqual((float(num_info_bits) / block_size, 
), (polar_encoder.rate(), ))
         self.assertFalse(polar_encoder.set_frame_size(10))
 
-    def test_002_work_function(self):
-        block_size = 256
-        num_info_bits = 128
-        num_frozen_bits = block_size - num_info_bits
-        frozen_bit_positions = cc.frozen_bit_positions(block_size, 
num_info_bits, 0.0)
-        frozen_bit_values = np.array([0] * num_frozen_bits,)
-        python_encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
-
+    def test_002_work_function_packed(self):
         is_packed = True
-        polar_encoder = fec.polar_encoder.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+        block_size = 256
+        num_info_bits = block_size // 2
 
-        data = np.ones(num_info_bits, dtype=int)
+        data, ref, polar_encoder = self.get_test_data(block_size, 
num_info_bits, 1, is_packed)
         src = blocks.vector_source_b(data, False)
         enc_block = extended_encoder(polar_encoder, None, '11')
         snk = blocks.vector_sink_b(1)
 
         self.tb.connect(src, enc_block, snk)
         self.tb.run()
-        print(self.tb.edge_list())
 
         res = np.array(snk.data()).astype(dtype=int)
-        penc = python_encoder.encode(data)
-
-        print(res)
-        print(penc)
-        self.assertTupleEqual(tuple(res), tuple(penc))
+        self.assertTupleEqual(tuple(res), tuple(ref))
 
-    def test_003_big_input(self):
-        is_packed = True
-        num_blocks = 30
+    def test_003_work_function_unpacked(self):
+        is_packed = False
         block_size = 256
-        num_info_bits = 128
-        num_frozen_bits = block_size - num_info_bits
-        frozen_bit_positions = cc.frozen_bit_positions(block_size, 
num_info_bits, 0.0)
-        frozen_bit_values = np.array([0] * num_frozen_bits,)
-        python_encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+        num_info_bits = block_size // 2
 
-        polar_encoder = fec.polar_encoder.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+        data, ref, polar_encoder = self.get_test_data(block_size, 
num_info_bits, 1, is_packed)
+        src = blocks.vector_source_b(data, False)
+        enc_block = extended_encoder(polar_encoder, None, '11')
+        snk = blocks.vector_sink_b(1)
 
-        data = np.array([], dtype=int)
-        ref = np.array([], dtype=int)
+        self.tb.connect(src, enc_block, snk)
+        self.tb.run()
 
-        for i in range(num_blocks):
-            d = np.random.randint(2, size=num_info_bits)
-            data = np.append(data, d)
-            ref = np.append(ref, python_encoder.encode(d))
+        res = np.array(snk.data()).astype(dtype=int)
+        self.assertTupleEqual(tuple(res), tuple(ref))
 
+    def test_004_big_input(self):
+        is_packed = False
+        num_blocks = 30
+        block_size = 1024
+        num_info_bits = block_size // 8
 
+        data, ref, polar_encoder = self.get_test_data(block_size, 
num_info_bits, num_blocks, is_packed)
         src = blocks.vector_source_b(data, False)
         enc_block = extended_encoder(polar_encoder, None, '11')
         snk = blocks.vector_sink_b(1)
@@ -111,6 +106,22 @@ class test_polar_encoder(gr_unittest.TestCase):
         print(ref)
         self.assertTupleEqual(tuple(res), tuple(ref))
 
+    def get_test_data(self, block_size, num_info_bits, num_blocks, is_packed):
+        num_frozen_bits = block_size - num_info_bits
+        frozen_bit_positions = cc.frozen_bit_positions(block_size, 
num_info_bits, 0.0)
+        frozen_bit_values = np.array([0] * num_frozen_bits,)
+        python_encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+
+        data = np.array([], dtype=int)
+        ref = np.array([], dtype=int)
+        for i in range(num_blocks):
+            d = np.random.randint(2, size=num_info_bits)
+            data = np.append(data, d)
+            ref = np.append(ref, python_encoder.encode(d))
+        polar_encoder = fec.polar_encoder.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+        return data, ref, polar_encoder
+
+
 
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]