Commit 6d055324 authored by Kevin JOLY's avatar Kevin JOLY

Update flooded MS decoder

- Rename/cleanup some variables
- Use array of size for vn and cn initialization
- Use array of size for vn addressing
- Compute cn offset prior to loops
parent 0c72b1a9
......@@ -11,15 +11,18 @@ CDecoder_MS_fixed_flooded::CDecoder_MS_fixed_flooded()
// We allocate a max of cn_deg_max per CN
p_vn_addr = new char *[nb_rows * cn_deg_max];
// We allocate a max of vn_deg_max per VN
p_cn_addr = new char *[nb_cols * vn_deg_max];
size_t* p_vn_addrSize = new size_t[nb_rows];
for(size_t i = 0; i < nb_rows*cn_deg_max; i++) {
p_vn_addr[i] = NULL;
for(size_t i = 0; i < nb_rows; i++) {
p_vn_addrSize[i] = 0;
}
for(size_t i = 0; i < nb_cols*vn_deg_max; i++) {
p_cn_addr[i] = NULL;
// We allocate a max of vn_deg_max per VN
p_cn_addr = new char *[nb_cols * vn_deg_max];
p_cn_addrSize = new size_t[nb_cols];
for(size_t i = 0; i < nb_cols; i++) {
p_cn_addrSize[i] = 0;
}
/* Iterate over the entire matrix H */
......@@ -34,35 +37,39 @@ CDecoder_MS_fixed_flooded::CDecoder_MS_fixed_flooded()
*/
row = edge_idx / cn_deg_max; // Also indicates the current CN
// Find the next empty slot
vn_slot_offset = 0;
cn_slot_offset = 0;
while(p_vn_addr[row*cn_deg_max + vn_slot_offset] != NULL) {
vn_slot_offset++;
if(vn_slot_offset == cn_deg_max) {
std::cout << "offset out of bound" << std::endl;
break;
}
// Associate vn addr to cn index, and cn addr to vn index
vn_slot_offset = p_vn_addrSize[row];
cn_slot_offset = p_cn_addrSize[vn_idx];
if (p_vn_addrSize[row] < cn_deg_max) {
p_vn_addrSize[row]++;
} else {
std::cerr << "vn_addr offset out of bound" << std::endl;
break;
}
while(p_cn_addr[vn_idx*vn_deg_max + cn_slot_offset] != NULL) {
cn_slot_offset++;
if(cn_slot_offset == vn_deg_max) {
std::cout << "offset out of bound" << std::endl;
break;
}
if (p_cn_addrSize[vn_idx] < vn_deg_max) {
p_cn_addrSize[vn_idx]++;
} else {
std::cerr << "cn_addr offset out of bound" << std::endl;
break;
}
p_vn_addr[row*cn_deg_max + vn_slot_offset] =
&var_msgs[vn_idx*vn_deg_max + cn_slot_offset];
&_vn_msgs[vn_idx*vn_deg_max + cn_slot_offset];
p_cn_addr[vn_idx*vn_deg_max + cn_slot_offset] =
&check_msgs[row*cn_deg_max + vn_slot_offset];
&_cn_msgs[row*cn_deg_max + vn_slot_offset];
}
delete p_vn_addrSize;
}
CDecoder_MS_fixed_flooded::~CDecoder_MS_fixed_flooded()
{
delete p_vn_addr;
delete p_cn_addr;
delete p_cn_addrSize;
}
void CDecoder_MS_fixed_flooded::decode(
......@@ -70,10 +77,6 @@ void CDecoder_MS_fixed_flooded::decode(
char Rprime_fix[],
int nombre_iterations)
{
char *llr_vn = var_nodes;
char *vn = CDecoder_fixed_flooded::var_nodes;
char *vn_msgs = CDecoder_fixed_flooded::var_msgs;
char *cn_msgs = CDecoder_fixed_flooded::check_msgs;
size_t vn_deg = vn_deg_max;
size_t cn_deg = cn_deg_max;
const size_t nb_vn = _N; // _N is number of VN
......@@ -84,7 +87,7 @@ void CDecoder_MS_fixed_flooded::decode(
/* Initialize variable node messages */
for(size_t i = 0; i < nb_vn; i++) {
for(size_t j = 0; j < vn_deg; j++) {
vn_msgs[i*vn_deg + j] = llr_vn[i];
_vn_msgs[i*vn_deg + j] = var_nodes[i];
}
}
......@@ -97,11 +100,12 @@ void CDecoder_MS_fixed_flooded::decode(
*/
for(size_t cn_idx = 0; cn_idx < nb_cn; cn_idx++) {
int cn_offset = cn_idx*cn_deg_max;
/* FIXME : in DVB-S2, the H matrix has one row with different degree:
* the last one. */
cn_deg = cn_idx == (nb_cn-1) ? DEG_2 : cn_deg_max; /* TODO JKI Move this out of loops */
/* TODO JKI : compute cn_idx*cn_deg_max once for all */
/* We compute a different estimate (the message sent), for each
* neighbouring VN */
for(size_t edge_idx = 0; edge_idx < cn_deg; edge_idx++) {
......@@ -110,13 +114,13 @@ void CDecoder_MS_fixed_flooded::decode(
/* TODO JKI : compute global sign and minLLR */
for(size_t other_edge_idx = 0; other_edge_idx < cn_deg; other_edge_idx++) {
if(other_edge_idx == edge_idx) continue;
char msg = *p_vn_addr[cn_idx*cn_deg_max + other_edge_idx];
char msg = *p_vn_addr[cn_offset + other_edge_idx];
char abs_msg = (msg >= 0 ? msg : -msg);
sign *= (msg >= 0) ? -1 : 1;
minLLR = minLLR > abs_msg ? abs_msg : minLLR;
}
cn_msgs[cn_idx*cn_deg_max + edge_idx] = (sign * minLLR);
_cn_msgs[cn_offset + edge_idx] = (sign * minLLR);
}
}
......@@ -126,37 +130,31 @@ void CDecoder_MS_fixed_flooded::decode(
* 2) A new estimate to be kept to itself
*/
for(size_t vn_idx = 0; vn_idx < nb_vn; vn_idx++) {
int estimate_acc = llr_vn[vn_idx];
int estimate_acc = var_nodes[vn_idx];
for(
size_t edge_idx = 0;
edge_idx < vn_deg_max && p_cn_addr[vn_idx*vn_deg_max + edge_idx] != NULL;
edge_idx++)
for(size_t edge_idx = 0; edge_idx < p_cn_addrSize[vn_idx]; edge_idx++)
{
estimate_acc += *p_cn_addr[vn_idx*vn_deg_max + edge_idx];
}
if(estimate_acc > 127) vn[vn_idx] = 127;
else if(estimate_acc < -127) vn[vn_idx] = -127;
else vn[vn_idx] = (char)estimate_acc;
if(estimate_acc > 127) _vn_est[vn_idx] = 127;
else if(estimate_acc < -127) _vn_est[vn_idx] = -127;
else _vn_est[vn_idx] = (char)estimate_acc;
for(
size_t edge_idx = 0;
edge_idx < vn_deg_max && p_cn_addr[vn_idx*vn_deg_max + edge_idx] != NULL;
edge_idx++)
for(size_t edge_idx = 0; edge_idx < p_cn_addrSize[vn_idx]; edge_idx++)
{
int msg = *p_cn_addr[vn_idx*vn_deg_max + edge_idx];
int vn_msg = estimate_acc - msg;
if(vn_msg > 127) vn_msgs[vn_idx*vn_deg_max + edge_idx] = 127;
else if(vn_msg < -127) vn_msgs[vn_idx*vn_deg_max + edge_idx] = -127;
else vn_msgs[vn_idx*vn_deg_max + edge_idx] = (char)vn_msg;
if(vn_msg > 127) _vn_msgs[vn_idx*vn_deg_max + edge_idx] = 127;
else if(vn_msg < -127) _vn_msgs[vn_idx*vn_deg_max + edge_idx] = -127;
else _vn_msgs[vn_idx*vn_deg_max + edge_idx] = (char)vn_msg;
}
}
}
/* Hard decision */
for(size_t vn_idx = 0; vn_idx < nb_vn; vn_idx++) {
Rprime_fix[vn_idx] = vn[vn_idx] > threshold ? 1 : 0;
Rprime_fix[vn_idx] = _vn_est[vn_idx] > threshold ? 1 : 0;
}
}
......@@ -8,6 +8,8 @@ protected:
char **p_vn_addr; // From a CN perspective, the addresses of all neighbouring VNs
char **p_cn_addr; // From a VN perspective, the addresses of all neighbouring CNs
size_t *p_cn_addrSize;
public:
CDecoder_MS_fixed_flooded();
~CDecoder_MS_fixed_flooded();
......
......@@ -5,16 +5,16 @@
CDecoder_fixed_flooded::CDecoder_fixed_flooded()
{
var_nodes = new char[NOEUD];
var_msgs = new char[vn_deg_max * _N];
check_msgs = new char[cn_deg_max * _K];
_vn_est = new char[NOEUD];
_vn_msgs = new char[vn_deg_max * _N];
_cn_msgs = new char[cn_deg_max * _K];
}
CDecoder_fixed_flooded::~CDecoder_fixed_flooded()
{
//delete var_nodes;
delete var_msgs;
delete check_msgs;
delete _vn_est;
delete _vn_msgs;
delete _cn_msgs;
}
void CDecoder_fixed_flooded::decode(float var_nodes[], char Rprime_fix[], int nombre_iterations)
......
......@@ -13,9 +13,9 @@ class CDecoder_fixed_flooded : public CDecoder_fixed {
protected:
const size_t cn_deg_max = DEG_1;
const size_t vn_deg_max = DEG_VN_MAX; // FIXME : find this constant somewhere
char *var_msgs;
char *check_msgs;
char *var_nodes;
char *_vn_msgs;
char *_cn_msgs;
char *_vn_est;
public:
CDecoder_fixed_flooded();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment