/* * ===================================================================================== * * Filename: ldgm-session.cpp * * Description: * * Version: 1.0 * Created: 04/12/2012 01:03:23 PM * Revision: none * Compiler: gcc * * Author: Milan Kabat (), kabat@ics.muni.cz * Organization: * * ===================================================================================== */ #ifdef HAVE_CONFIG_H #include "config.h" #include "config_unix.h" #include "config_win32.h" #endif // HAVE_CONFIG_H #include #include #include #include #include #include #include "crypto/crc.h" #include "ldgm-session.h" #include "timer-util.h" using namespace std; /* *-------------------------------------------------------------------------------------- * Class: LDGM_session * Method: LDGM_session * Description: constructor *-------------------------------------------------------------------------------------- */ void LDGM_session::set_pcMatrix ( char* fname) { FILE *f; f = fopen(fname, "rb"); if (!f) { printf ( "Error opening matrix file\n" ); printf ( "exiting\n" ); abort(); } unsigned int k_f, m_f, w_f; if (fscanf(f, "%d %d %d", &k_f, &m_f, &w_f) != 3) { throw string("Parity matrix read error!"); } // printf ( "In matrix file: K %d M %d Columns %d\n", k_f, m_f, w_f ); if ( k_f != param_k || m_f != param_m) { ostringstream oss; oss << "Parity matrix size mismatch\nExpected K = " << param_k << "% M = " << param_m << "\nReceived K = " << k_f << ", M = " << m_f << "\n"; throw oss.str(); } fseek (f, 1, SEEK_CUR ); pcm = (int*) malloc(w_f*param_m*sizeof(int)); for ( int i = 0; i < (int)w_f*param_m; i++) { if (fread ( pcm+i, sizeof(int), 1, f) != 1) { throw string("Parity matrix read error!"); } } this->max_row_weight = w_f - 2; //w_f stores number of columns in adjacency list /* for ( int i = 0; i < param_m; i++) * { * for ( int j = 0; j < w_f; j++) * printf ( "[%3d]", (unsigned int)(pcm[i*w_f+j]) ); * printf ( "\n" ); * } */ fclose(f); /* * this->max_row_weight = 0; * int max_weight = 0; * for ( int i = 0; i < param_m; ++i) { * for ( int j = 0; j < param_k; ++j) { * if(*(matrix + i*param_k + j) == 1) { * *(pcMatrix + i*param_k + j) = *(matrix + i*param_k + j); * max_weight++; * } * } * if ( max_weight > this->max_row_weight ) * this->max_row_weight = max_weight; * max_weight = 0; * } * * pcm = (int*) malloc (m*(max_row_weight+2)*sizeof(int*)); * struct coding_params params; * params.m = m; * params.k = k; * params.max_row_weight = max_row_weight; * * make_compact_pcm ( matrix, pcm, params); */ return ; } /* ----- end of method Coding_session::set_pcMatrix ----- */ char* LDGM_session::encode_frame ( char* frame, int frame_size, int* out_buf_size ) { //printf("encode_frame\n"); struct timeval t0,t1; gettimeofday(&t0, 0); int buf_size; int ps; short header_size = LDGM_session::HEADER_SIZE; int align_coef = param_k*sizeof(int); if ( (frame_size + header_size) % align_coef == 0 ) buf_size = frame_size + header_size; else buf_size = ( ( (frame_size + header_size) / align_coef ) + 1 ) * align_coef; ps = buf_size/param_k; packet_size = ps; //printf ( "ps: %d\n", ps ); buf_size += param_m*ps; *out_buf_size = buf_size; void *out_buf; out_buf = alloc_buf(buf_size); if (!out_buf) { printf ( "Unable to allocate memory\n" ); return NULL; } memset(out_buf, 0, buf_size); //Insert frame size and copy input data into buffer int *hdr = (int*)out_buf; *hdr = frame_size; memcpy( ((char*)out_buf) + header_size, frame, frame_size); //Timer_util t; //printf("2buf_size %d\n",buf_size); //printf("2packet_size %d\n",packet_size); this->encode ( (char*)out_buf, ((char*)out_buf)+param_k*ps ); gettimeofday(&t1,0); long elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; // printf("time: %e\n",elapsed/1000.0 ); this->elapsed_sum2+=elapsed/1000.0; this->no_frames2++; return (char*)out_buf; // printf ( "SSE: %.3lf\n", t.elapsed_time(start, end) ); /* void *out_buf_check; * error = posix_memalign(&out_buf_check, 16, buf_size); * memset(out_buf_check, 0, buf_size); * hdr = (int*)out_buf_check; * *hdr = frame_size; * memcpy(((char*)out_buf_check)+header_size, frame, frame_size); * clock_gettime(CLOCK_MONOTONIC, &start); * encode_naive ( (char*)out_buf, ((char*)out_buf_check)+param_k*ps ); * clock_gettime(CLOCK_MONOTONIC, &end); * printf ( "CPU: %.3lf\n", t.elapsed_time(start, end) ); * * int e = memcmp(out_buf, out_buf_check, buf_size); * printf ( "memcpy on parities: %d\n", e ); * char *a = (char*)out_buf; * char *b = (char*)out_buf_check; * bool equal = true; * int idx = 0; * for ( int i = 0; i < param_m*ps; i++) * { * if(a[i] != b[i]) * { * idx = i; * printf ( "Error at index %d: %d vs %d\n", i, (unsigned char)a[i], * (unsigned char)b[i] ); * equal = false; * } * } * * printf ( "Parities %s match.\n", (equal)?"":"do not" ); */ // printf ( "\n\nEncoded block:\n" ); // printf ( "%-13s\v%10d B\n", "Frame hdr size:", header_size ); // printf ( "%-13s\v%10d B\n", "Frame size:", frame_size ); // printf ( "Padding size:\t%-d B\n", buf_size-frame_size-header_size-param_m*ps ); // printf ( "Parity size:\t%-d B\n", param_m*ps ); // printf ( "-------------------------------\n"); // printf ( "Total block size:\t%d B\n", buf_size ); // printf ( "Symbol size:\t%d\n\n\n", ps ); } char* LDGM_session::encode_hdr_frame ( char *my_hdr, int my_hdr_size, char* frame, int frame_size, int* out_buf_size ) { int buf_size; int ps; short header_size = LDGM_session::HEADER_SIZE; int overall_size = my_hdr_size + frame_size; int align_coef = param_k*sizeof(int); if ( (overall_size + header_size) % align_coef == 0 ) buf_size = overall_size + header_size; else buf_size = ( ( (overall_size + header_size) / align_coef ) + 1 ) * align_coef; ps = buf_size/param_k; packet_size = ps; // printf ( "ps: %d\n", ps ); buf_size += param_m*ps; *out_buf_size = buf_size; void *out_buf; out_buf = alloc_buf(buf_size); if (!out_buf) { printf ( "Unable to allocate aligned memory\n" ); return NULL; } memset(out_buf, 0, buf_size); //Insert frame size and copy input data into buffer int32_t *hdr = (int32_t*)out_buf; *hdr = overall_size; memcpy( ((char*)out_buf) + header_size, my_hdr, my_hdr_size); memcpy( ((char*)out_buf) + header_size + my_hdr_size, frame, frame_size); #if 0 int my_frame_size=my_hdr_size+frame_size; // printf("my_frame_size: %d\n",my_frame_size ); int crc; crc = crc32buf((char*)out_buf+header_size,my_frame_size); memcpy( ((char*)out_buf) + 4, &crc, 4); memcpy( ((char*)out_buf) + 8, &my_frame_size, 4); assert(LDGM_session::HEADER_SIZE >= 12); #endif //Timer_util t; struct timeval t0, t1; gettimeofday(&t0, 0); this->encode ( (char*)out_buf, ((char*)out_buf)+param_k*ps ); gettimeofday(&t1,0); long elapsed; elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; // printf("time: %e\n",elapsed/1000.0 ); this->elapsed_sum2+=elapsed/1000.0; this->no_frames2++; // gettimeofday(&t1,0); // long elapsed; // elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec; // // printf("time: %e\n",elapsed/1000.0 ); // this->elapsed_sum2+=elapsed/1000.0; // this->no_frames2++; // i++; // if(i%100==0){ // printf("TIME GPU: %f ms\n",this->elapsed_sum2/(double)this->no_frames2 ); // printf("time: %f ms\n",elapsed/1000.0 ); // } // printf ( "SSE: %.3lf\n", t.elapsed_time(start, end) ); /* void *out_buf_check; * error = posix_memalign(&out_buf_check, 16, buf_size); * memset(out_buf_check, 0, buf_size); * hdr = (int*)out_buf_check; * *hdr = frame_size; * memcpy(((char*)out_buf_check)+header_size, frame, frame_size); * clock_gettime(CLOCK_MONOTONIC, &start); * encode_naive ( (char*)out_buf, ((char*)out_buf_check)+param_k*ps ); * clock_gettime(CLOCK_MONOTONIC, &end); * printf ( "CPU: %.3lf\n", t.elapsed_time(start, end) ); * * int e = memcmp(out_buf, out_buf_check, buf_size); * printf ( "memcpy on parities: %d\n", e ); * char *a = (char*)out_buf; * char *b = (char*)out_buf_check; * bool equal = true; * int idx = 0; * for ( int i = 0; i < param_m*ps; i++) * { * if(a[i] != b[i]) * { * idx = i; * printf ( "Error at index %d: %d vs %d\n", i, (unsigned char)a[i], * (unsigned char)b[i] ); * equal = false; * } * } * * printf ( "Parities %s match.\n", (equal)?"":"do not" ); */ // printf ( "\n\nEncoded block:\n" ); // printf ( "%-13s\v%10d B\n", "Frame hdr size:", header_size ); // printf ( "%-13s\v%10d B\n", "Frame size:", frame_size ); // printf ( "Padding size:\t%-d B\n", buf_size-frame_size-header_size-param_m*ps ); // printf ( "Parity size:\t%-d B\n", param_m*ps ); // printf ( "-------------------------------\n"); // printf ( "Total block size:\t%d B\n", buf_size ); // printf ( "Symbol size:\t%d\n\n\n", ps ); return (char*)out_buf; } /* * === FUNCTION ====================================================================== * Name: create_edges * Description: * ===================================================================================== */ void LDGM_session::create_edges ( Tanner_graph *graph ) { map::iterator it; // printf ( "graph: %p, param_k: %d, param_m: %d\n", graph, param_k, param_m ); for ( int m = 0; m < param_m; ++m) { for ( int k = 0; k < max_row_weight+2; ++k ) { int idx = pcm [ m*(max_row_weight+2) + k]; if( idx > -1 ) { it = graph->nodes.find(idx); (*it).second.neighbours.push_back(param_k + param_m + m); it = graph->nodes.find(param_k + param_m + m); (*it).second.neighbours.push_back(idx); } } } /* it = graph->nodes.find(0); * while ( it != graph->nodes.end() ) * { * printf ( "\nneighbours of node %d: ", it->first ); * for (vector::iterator i = it->second.neighbours.begin(); * i != it->second.neighbours.end(); ++i) * printf ( "%d, ", *i ); * it++; * } */ //add edges representing the staircase matrix /* for ( int i = param_k + param_m; i < param_k + 2*param_m; ++i) { * it = graph->nodes.find(i); * (*it).second.neighbours.push_back(i - param_m); * it = graph->nodes.find(i - param_m); * (*it).second.neighbours.push_back(i); * if(i > param_m + param_k) { * it = graph->nodes.find(i); * (*it).second.neighbours.push_back(i - param_m - 1); * it = graph->nodes.find(i - param_m - 1); * (*it).second.neighbours.push_back(i); * } * } */ return ; } /* ----- end of function create_edges ----- */ bool LDGM_session::needs_decoding ( Tanner_graph *graph ) { for ( int i = 0; i < param_k; i++) if( ! graph->nodes.find(i)->second.isDone() ) return true; return false; } /* ----- end of method LDGM_session::needs_decoding ----- */ LDGM_session::~LDGM_session() { free(pcm); }