commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 01/17: gr-fec: Fix memory allocation issue


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/17: gr-fec: Fix memory allocation issue during encoding.
Date: Thu, 14 Apr 2016 20:43:01 +0000 (UTC)

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

jcorgan pushed a commit to branch maint
in repository gnuradio.

commit aef116e28d02a39a7e30e937574cb35876c15b5b
Author: tracierenea <address@hidden>
Date:   Mon Mar 28 20:49:53 2016 -0500

    gr-fec: Fix memory allocation issue during encoding.
    
    I think that declaring these temporary matrix variables in the header (and 
then allocating memory for them in the constructor) is problematic when using 
parallelism = 1 or 2, as is the case when using the BER Curve Gen./Sink blocks.
    
    When parallelism is in effect, there are multiple "sub" flowgraphs in 
process and therefore multiple, probably very-close-to-simultaneous, calls to 
encode(). I think what's happening is that these temp matrices are being 
overwritten in memory by the next call to encode() before the current call to 
encode() is done with them.
    
    I know that such repeated allocate/free calls in the encode() function is 
not ideal or efficient, I can't think of a better way to do this (for now) and 
allow for parallelism.
    
    With this change, these matrices are no longer member variables of the 
class, so I've removed the "d_" prefix from the variable names.
---
 gr-fec/lib/ldpc_H_matrix_impl.cc | 83 +++++++++++++++++++++++-----------------
 gr-fec/lib/ldpc_H_matrix_impl.h  |  4 --
 2 files changed, 48 insertions(+), 39 deletions(-)

diff --git a/gr-fec/lib/ldpc_H_matrix_impl.cc b/gr-fec/lib/ldpc_H_matrix_impl.cc
index ae6fb9a..4d37899 100644
--- a/gr-fec/lib/ldpc_H_matrix_impl.cc
+++ b/gr-fec/lib/ldpc_H_matrix_impl.cc
@@ -67,16 +67,6 @@ namespace gr {
         // encoder)
         d_par_bits_last = false;
 
-        d_s = gsl_matrix_alloc(d_k, 1);
-        d_temp1 = gsl_matrix_alloc(B()->size1, d_s->size2);
-        d_temp2 = gsl_matrix_alloc(T()->size1, 1);
-        d_temp3 = gsl_matrix_alloc(E()->size1, d_temp2->size2);
-        d_temp4 = gsl_matrix_alloc(D()->size1, d_s->size2);
-        d_temp5 = gsl_matrix_alloc(d_temp4->size1, d_temp3->size2);
-        d_p1 = gsl_matrix_alloc(T()->size1, 1);
-        d_p2 = gsl_matrix_alloc(phi_inverse()->size1, d_temp5->size2);
-        d_temp6 = gsl_matrix_alloc(A()->size1, d_p2->size2);
-        d_temp7 = gsl_matrix_alloc(d_temp6->size1, d_temp1->size2);
       } // Constructor
 
       const gsl_matrix*
@@ -259,42 +249,75 @@ namespace gr {
       ldpc_H_matrix_impl::encode(unsigned char *outbuffer,
                                  const unsigned char *inbuffer) const
       {
+
+        // Temporary matrix for storing stages of encoding.
+        gsl_matrix *s, *p1, *p2;
+        gsl_matrix *temp1, *temp2, *temp3, *temp4, *temp5, *temp6, *temp7;
+
         unsigned int index, k = d_k;
+        s = gsl_matrix_alloc(k, 1);
         for (index = 0; index < k; index++) {
           double value = static_cast<double>(inbuffer[index]);
-          gsl_matrix_set(d_s, index, 0, value);
+          gsl_matrix_set(s, index, 0, value);
         }
 
         // Solve for p2 (parity part). By using back substitution,
         // the overall complexity of determining p2 is O(n + g^2).
-        mult_matrices_mod2(d_temp1, B(), d_s);
-        back_solve_mod2(d_temp2, T(), d_temp1);
-        mult_matrices_mod2(d_temp3, E(), d_temp2);
-        mult_matrices_mod2(d_temp4, D(), d_s);
-        add_matrices_mod2(d_temp5, d_temp4, d_temp3);
-        mult_matrices_mod2(d_p2, phi_inverse(), d_temp5);
+        temp1 = gsl_matrix_alloc(B()->size1, s->size2);
+        mult_matrices_mod2(temp1, B(), s);
+
+        temp2 = gsl_matrix_alloc(T()->size1, 1);
+        back_solve_mod2(temp2, T(), temp1);
+
+        temp3 = gsl_matrix_alloc(E()->size1, temp2->size2);
+        mult_matrices_mod2(temp3, E(), temp2);
+
+        temp4 = gsl_matrix_alloc(D()->size1, s->size2);
+        mult_matrices_mod2(temp4, D(), s);
+
+        temp5 = gsl_matrix_alloc(temp4->size1, temp3->size2);
+        add_matrices_mod2(temp5, temp4, temp3);
+
+        p2 = gsl_matrix_alloc(phi_inverse()->size1, temp5->size2);
+        mult_matrices_mod2(p2, phi_inverse(), temp5);
 
         // Solve for p1 (parity part). By using back substitution,
         // the overall complexity of determining p1 is O(n).
-        mult_matrices_mod2(d_temp6, A(), d_p2);
-        add_matrices_mod2(d_temp7, d_temp6, d_temp1);
-        back_solve_mod2(d_p1, T(), d_temp7);
+        temp6 = gsl_matrix_alloc(A()->size1, p2->size2);
+        mult_matrices_mod2(temp6, A(), p2);
+
+        temp7 = gsl_matrix_alloc(temp6->size1, temp1->size2);
+        add_matrices_mod2(temp7, temp6, temp1);
+
+        p1 = gsl_matrix_alloc(T()->size1, 1);
+        back_solve_mod2(p1, T(), temp7);
 
         // Populate the codeword to be output
-        unsigned int p1_length = (*d_p1).size1;
-        unsigned int p2_length = (*d_p2).size1;
+        unsigned int p1_length = (*p1).size1;
+        unsigned int p2_length = (*p2).size1;
         for (index = 0; index < p1_length; index++) {
-          int value = gsl_matrix_get(d_p1, index, 0);
+          int value = gsl_matrix_get(p1, index, 0);
           outbuffer[index] = value;
         }
         for (index = 0; index < p2_length; index++) {
-          int value = gsl_matrix_get(d_p2, index, 0);
+          int value = gsl_matrix_get(p2, index, 0);
           outbuffer[p1_length+index] = value;
         }
         for (index = 0; index < k; index++) {
-          int value = gsl_matrix_get(d_s, index, 0);
+          int value = gsl_matrix_get(s, index, 0);
           outbuffer[p1_length+p2_length+index] = value;
         }
+
+        // Free temporary matrices
+        gsl_matrix_free(temp1);
+        gsl_matrix_free(temp2);
+        gsl_matrix_free(temp3);
+        gsl_matrix_free(temp4);
+        gsl_matrix_free(temp5);
+        gsl_matrix_free(temp6);
+        gsl_matrix_free(temp7);
+        gsl_matrix_free(p1);
+        gsl_matrix_free(p2);
       }
 
 
@@ -413,16 +436,6 @@ namespace gr {
 
       ldpc_H_matrix_impl::~ldpc_H_matrix_impl()
       {
-        // Free temporary matrices
-        gsl_matrix_free(d_temp1);
-        gsl_matrix_free(d_temp2);
-        gsl_matrix_free(d_temp3);
-        gsl_matrix_free(d_temp4);
-        gsl_matrix_free(d_temp5);
-        gsl_matrix_free(d_temp6);
-        gsl_matrix_free(d_temp7);
-        gsl_matrix_free(d_p1);
-        gsl_matrix_free(d_p2);
 
         // Call the gsl_matrix_free function to free memory.
         gsl_matrix_free (d_phi_inverse_ptr);
diff --git a/gr-fec/lib/ldpc_H_matrix_impl.h b/gr-fec/lib/ldpc_H_matrix_impl.h
index b4893ce..89ea4de 100644
--- a/gr-fec/lib/ldpc_H_matrix_impl.h
+++ b/gr-fec/lib/ldpc_H_matrix_impl.h
@@ -43,10 +43,6 @@ namespace gr {
         gsl_matrix_view d_T_view;
         gsl_matrix *d_phi_inverse_ptr;
 
-        // Temporary matrix for storing stages of encoding.
-        gsl_matrix *d_s, *d_p1, *d_p2;
-        gsl_matrix *d_temp1, *d_temp2, *d_temp3, *d_temp4, *d_temp5, *d_temp6, 
*d_temp7;
-
         //! Sets the submatrix variables needed for encoding
         void set_parameters_for_encoding();
 



reply via email to

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