/* * Note: throughout the packet collecting process, the decoding matrix * is maintained an upper triangular form. */ void process_packet_CBD(struct decoding_context_CBD *dec_ctx, struct snc_packet *pkt) { static char fname[] = "snc_process_packet_CBD"; dec_ctx->overhead += 1; int i, j, k; GF_ELEMENT quotient; int gensize = dec_ctx->sc->params.size_g; int pktsize = dec_ctx->sc->params.size_p; int numpp = dec_ctx->sc->snum + dec_ctx->sc->cnum; // transform GNC encoding vector to full length GF_ELEMENT *ces = calloc(numpp, sizeof(GF_ELEMENT)); if (ces == NULL) fprintf(stderr, "%s: calloc ces failed\n", fname); for (i=0; i<gensize; i++) { int index = dec_ctx->sc->gene[pkt->gid]->pktid[i]; if (dec_ctx->sc->params.bnc) { ces[index] = get_bit_in_array(pkt->coes, i); } else { ces[index] = pkt->coes[i]; } } /* Process full-length encoding vector against decoding matrix */ int lastDoF = dec_ctx->DoF; int pivot = process_vector_CBD(dec_ctx, ces, pkt->syms); free(ces); ces = NULL; if (get_loglevel() == TRACE) printf("received %d DoF: %d\n", dec_ctx->overhead, dec_ctx->DoF-lastDoF); // If the number of received DoF is equal to NUM_SRC, apply the parity-check matrix. // The messages corresponding to rows of parity-check matrix are all-zero. if (dec_ctx->DoF == dec_ctx->sc->snum) { dec_ctx->de_precode = 1; /*Mark de_precode before applying precode matrix*/ int missing_DoF = apply_parity_check_matrix(dec_ctx); if (get_loglevel() == TRACE) printf("After applying the parity-check matrix, %d DoF are missing.\n", missing_DoF); dec_ctx->DoF = numpp - missing_DoF; } if (dec_ctx->DoF == dec_ctx->sc->snum + dec_ctx->sc->cnum) { finish_recovering_CBD(dec_ctx); } }
/* is_enabled Does not check if level is set to zero. */ bool loglevel<true>::is_enabled ( ) const { return ( ((this->lvl % 2) != 0) && this->lvl <= get_loglevel() ); }
bool nscapi::core_wrapper::should_log(NSCAPI::nagiosReturn msgType) const { enum log_status {unknown, set }; static NSCAPI::log_level::level level = NSCAPI::log_level::info; static log_status status = unknown; if (status == unknown) { level = get_loglevel(); status = set; } return nscapi::logging::matches(level, msgType); }
int32_t FileLogDevice::write(const struct log_message_t& log_message) { if (get_loglevel() > log_message.loglevel) { return 0; } char buffer[1024] = {0}; int32_t split_policy; int32_t nformated; nformated = format_log_message(buffer, 1022, log_message); split_policy = get_split_policy(); { Guard<Mutex> guard(&_mutex); if (!is_opened()) { return -1; } if (BGCC_LOG_SPLIT_POLICY_BY_TIME == split_policy) { if (exec_time_split_policy() != 0) { return -1; } } else { if (exec_size_split_policy(nformated) != 0) { return -1; } } if (!is_opened()) { return -1; } fwrite(buffer, nformated, 1, _fp); _file_size += nformated; fflush(_fp); } return 0; }
/** * Finish CBD decoding * This routine converts decoding matrix from upper triangular * form to diagonal. */ static void finish_recovering_CBD(struct decoding_context_CBD *dec_ctx) { int gensize = dec_ctx->sc->params.size_g; int pktsize = dec_ctx->sc->params.size_p; int numpp = dec_ctx->sc->snum + dec_ctx->sc->cnum; int i, j; int len; GF_ELEMENT quotient; for (i=numpp-1; i>=0; i--) { /* eliminate all nonzeros above diagonal elements from right to left*/ for (j=0; j<i; j++) { len = dec_ctx->row[j]->len; if (j+len <= i || dec_ctx->row[j]->elem[i-j] == 0) continue; assert(dec_ctx->row[i]->elem[0]); quotient = galois_divide(dec_ctx->row[j]->elem[i-j], dec_ctx->row[i]->elem[0]); galois_multiply_add_region(dec_ctx->message[j], dec_ctx->message[i], quotient, pktsize); dec_ctx->operations += (pktsize + 1); dec_ctx->ops3 += (pktsize + 1); dec_ctx->row[j]->elem[i-j] = 0; } /* convert diagonal to 1*/ if (dec_ctx->row[i]->elem[0] != 1) { galois_multiply_region(dec_ctx->message[i], galois_divide(1, dec_ctx->row[i]->elem[0]), pktsize); dec_ctx->operations += (pktsize + 1); dec_ctx->ops3 += (pktsize + 1); dec_ctx->row[i]->elem[0] = 1; } /* save decoded packet */ dec_ctx->sc->pp[i] = calloc(pktsize, sizeof(GF_ELEMENT)); memcpy(dec_ctx->sc->pp[i], dec_ctx->message[i], pktsize*sizeof(GF_ELEMENT)); } dec_ctx->finished = 1; if (get_loglevel() == TRACE) { int snum = dec_ctx->sc->snum; printf("Splitted operations: %f %f %f\n", (double) dec_ctx->ops1/snum/pktsize, (double) dec_ctx->ops2/snum/pktsize, (double) dec_ctx->ops3/snum/pktsize); } }
// Apply the parity-check matrix to the decoding matrix static int apply_parity_check_matrix(struct decoding_context_CBD *dec_ctx) { static char fname[] = "apply_parity_check_matrix"; int i, j, k; int num_of_new_DoF = 0; int gensize = dec_ctx->sc->params.size_g; int pktsize = dec_ctx->sc->params.size_p; int numpp = dec_ctx->sc->snum + dec_ctx->sc->cnum; // 1, Copy parity-check vectors to the nonzero rows of the decoding matrix GF_ELEMENT *ces = malloc(numpp*sizeof(GF_ELEMENT)); GF_ELEMENT *msg = malloc(pktsize*sizeof(GF_ELEMENT)); int p = 0; // index pointer to the parity-check vector that is to be copyed for (int p=0; p<dec_ctx->sc->cnum; p++) { memset(ces, 0, numpp*sizeof(GF_ELEMENT)); memset(msg, 0, pktsize*sizeof(GF_ELEMENT)); /* Set the coding vector according to parity-check bits */ NBR_node *varnode = dec_ctx->sc->graph->l_nbrs_of_r[p]->first; while (varnode != NULL) { ces[varnode->data] = varnode->ce; varnode = varnode->next; } ces[dec_ctx->sc->snum+p] = 1; int pivot = process_vector_CBD(dec_ctx, ces, msg); } free(ces); free(msg); /* Count available innovative rows */ int missing_DoF = 0; for (i=0; i<numpp; i++) { if (dec_ctx->row[i] == NULL) missing_DoF++; else if (dec_ctx->row[i]->elem[0] ==0 && get_loglevel() == TRACE) { printf("%s: row[%d]->elem[0] is 0\n", fname, i); } } return missing_DoF; }
int main(int argc, char **argv) { extern char *optarg; extern int optind, optopt; char *fname = NULL; char step = 0; int c; init(); /* check args * -f: read sudokus from file (- for stdin) */ while ((c = getopt(argc, argv, "f:vsh")) != EOF) { switch (c) { case 'f': fname = (char *) malloc(strlen(optarg)+1); if (fname == NULL) eprintf("malloc() failed:"); strncpy(fname, optarg, strlen(optarg)); fname[strlen(optarg)] = '\0'; break; case 'v': set_loglevel(get_loglevel() + 1); break; case 'h': usage(); exit(EXIT_SUCCESS); case 's': step = 1; break; default: break; } } /* if (step && verbose == 0) ++verbose; */ if (fname != NULL) { FILE *file; char *line; int bufsize = X*Y + 2; if (strcmp(fname, "-") == 0) file = stdin; else { file = fopen(fname, "r"); if (file == NULL) eprintf("Couldn't open file '%s':", fname); } line = (char *) malloc(bufsize); if (NULL == line) eprintf("malloc() failed:"); while (fgets(line, bufsize, file) != NULL) { if (line[0] == '#') continue; init(); parse_board(line); mode = MODE_NORMAL; if (step) mode = MODE_STEP; printf(line); solve(); } if (fileno(file) != STDIN_FILENO) fclose(file); free(line); free(fname); } else { /* try if there was a puzzle as argument */ if (argc > optind) { printf("Initializing the board ...\n"); if (parse_board(argv[optind]) != X*Y) { eprintf("Error parsing the puzzle"); } print_board(); mode = MODE_NORMAL; if (step) mode = MODE_STEP; solve(); } else { wprintf("Error: no puzzle(s) given"); usage(); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }
/* Process a full row vector against CBD decoding matrix */ static int process_vector_CBD(struct decoding_context_CBD *dec_ctx, GF_ELEMENT *vector, GF_ELEMENT *message) { static char fname[] = "process_vector_CBD"; int i, j, k; int pivot = -1; int pivotfound = 0; GF_ELEMENT quotient; int gensize = dec_ctx->sc->params.size_g; int pktsize = dec_ctx->sc->params.size_p; int numpp = dec_ctx->sc->snum + dec_ctx->sc->cnum; int rowop = 0; for (i=0; i<numpp; i++) { if (vector[i] != 0) { if (dec_ctx->row[i] != NULL) { /* There is a valid row saved for pivot-i, process against it */ assert(dec_ctx->row[i]->elem[0]); quotient = galois_divide(vector[i], dec_ctx->row[i]->elem[0]); galois_multiply_add_region(&(vector[i]), dec_ctx->row[i]->elem, quotient, dec_ctx->row[i]->len); galois_multiply_add_region(message, dec_ctx->message[i], quotient, pktsize); dec_ctx->operations += 1 + dec_ctx->row[i]->len + pktsize; if (!dec_ctx->de_precode) { dec_ctx->ops1 += 1 + dec_ctx->row[i]->len + pktsize; } else { dec_ctx->ops2 += 1 + dec_ctx->row[i]->len + pktsize; } rowop += 1; } else { pivotfound = 1; pivot = i; break; } } } if (pivotfound == 1) { /* Save it to the corresponding row */ dec_ctx->row[pivot] = (struct row_vector*) malloc(sizeof(struct row_vector)); if (dec_ctx->row[pivot] == NULL) fprintf(stderr, "%s: malloc dec_ctx->row[%d] failed\n", fname, pivot); int len; if (!dec_ctx->de_precode && !dec_ctx->naive) { /* before de_precode every row is no more than gensize-width */ len = numpp - pivot > gensize ? gensize : numpp - pivot; } else { /* row bandwidth is indetermined, so being conservative here */ len = numpp - pivot; } dec_ctx->row[pivot]->len = len; dec_ctx->row[pivot]->elem = (GF_ELEMENT *) calloc(len, sizeof(GF_ELEMENT)); if (dec_ctx->row[pivot]->elem == NULL) fprintf(stderr, "%s: calloc dec_ctx->row[%d]->elem failed\n", fname, pivot); memcpy(dec_ctx->row[pivot]->elem, &(vector[pivot]), len*sizeof(GF_ELEMENT)); assert(dec_ctx->row[pivot]->elem[0]); memcpy(dec_ctx->message[pivot], message, pktsize*sizeof(GF_ELEMENT)); if (get_loglevel() == TRACE) printf("received-DoF %d new-DoF %d row_ops: %d\n", dec_ctx->DoF, pivot, rowop); dec_ctx->DoF += 1; } return pivot; }
void process_packet_PP(struct decoding_context_PP *dec_ctx, struct snc_packet *pkt) { static char fname[] = "snc_process_packet_PP"; dec_ctx->overhead += 1; int gensize = dec_ctx->sc->params.size_g; int pktsize = dec_ctx->sc->params.size_p; int numpp = dec_ctx->sc->snum; // start processing int i, j, k; GF_ELEMENT quotient; if (dec_ctx->stage == FORWARD) { // transform GNC encoding vector to full length (gensize) in case it is GF(2) and therefore was compressed GF_ELEMENT *ces0 = calloc(gensize, sizeof(GF_ELEMENT)); if (ces0 == NULL) fprintf(stderr, "%s: calloc ces0 failed\n", fname); if (dec_ctx->sc->params.bnc) { for (i=0; i<gensize; i++) ces0[i] = get_bit_in_array(pkt->coes, i); } else { memcpy(ces0, pkt->coes, gensize*sizeof(GF_ELEMENT)); } int pivot = dec_ctx->sc->gene[pkt->gid]->pktid[0];// By default, the coding coefficient of the pivot candidate is pkt->coes[0] int shift = 0; while (ces0[shift] == 0) { shift += 1; if (shift == gensize) { free(ces0); return; // pkt->coes is all zero, so this is a useless packet, just return. } } pivot = (pivot + shift) % numpp; GF_ELEMENT *ces_tmp = calloc(gensize, sizeof(GF_ELEMENT)); memcpy(ces_tmp, &(ces0[shift]), (gensize-shift)*sizeof(GF_ELEMENT)); // temporary place for multiply-add with existing rows // There is already a row with the same pivot in decoding matrix int rowlen = gensize - shift; while (dec_ctx->row[pivot] != NULL) { quotient = galois_divide(ces_tmp[0], dec_ctx->row[pivot]->elem[0]); galois_multiply_add_region(ces_tmp, dec_ctx->row[pivot]->elem, quotient, dec_ctx->row[pivot]->len); galois_multiply_add_region(pkt->syms, dec_ctx->message[pivot], quotient, pktsize); int newlen = rowlen > dec_ctx->row[pivot]->len ? rowlen : dec_ctx->row[pivot]->len; // new length of the vector after processed rowlen = newlen - 1; // the first element has been reduced to 0, so omit it memset(ces0, 0, sizeof(GF_ELEMENT)*gensize); memcpy(ces0, &(ces_tmp[1]), rowlen*sizeof(GF_ELEMENT)); // copy resultant vector back to ces0 dec_ctx->operations += 1 + dec_ctx->row[pivot]->len + pktsize; shift = 0; while (ces0[shift] == 0) { shift += 1; if (shift == newlen) { free(ces0); free(ces_tmp); return; // pkt->coes is reduced to zero, so this is a useless packet, just return. } } pivot = (pivot + 1 + shift) % numpp; memset(ces_tmp, 0, sizeof(GF_ELEMENT)*gensize); memcpy(ces_tmp, &(ces0[shift]), (rowlen-shift)*sizeof(GF_ELEMENT)); rowlen = rowlen - shift; } // Save the resultant row dec_ctx->row[pivot] = (struct row_vector*) malloc(sizeof(struct row_vector)); if (dec_ctx->row[pivot] == NULL) fprintf(stderr, "%s: malloc dec_ctx->row[%d] failed\n", fname, pivot); int len = rowlen; dec_ctx->row[pivot]->len = len; dec_ctx->row[pivot]->elem = (GF_ELEMENT *) calloc(len, sizeof(GF_ELEMENT)); if (dec_ctx->row[pivot]->elem == NULL) fprintf(stderr, "%s: calloc dec_ctx->row[%d]->elem failed\n", fname, pivot); memcpy(dec_ctx->row[pivot]->elem, ces_tmp, len*sizeof(GF_ELEMENT)); assert(dec_ctx->row[pivot]->elem[0]); memcpy(dec_ctx->message[pivot], pkt->syms, pktsize*sizeof(GF_ELEMENT)); dec_ctx->pivots += 1; if (get_loglevel() == TRACE) printf("pivot-candidates %d received %d\n", dec_ctx->pivots, dec_ctx->overhead); free(ces0); free(ces_tmp); } else if (dec_ctx->stage == FINALFORWARD) { // Previous final forward was not successful, and therefore it receives more packets to fill in the decoding matrix // Now always convert encoding vector to full length (numpp) GF_ELEMENT *ces1 = calloc(numpp, sizeof(GF_ELEMENT)); if (ces1 == NULL) fprintf(stderr, "%s: calloc ces1 failed\n", fname); for (i=0; i<gensize; i++) { int index = dec_ctx->sc->gene[pkt->gid]->pktid[i]; if (dec_ctx->sc->params.bnc) { ces1[index] = get_bit_in_array(pkt->coes, i); } else { ces1[index] = pkt->coes[i]; } } // Process the full length vector against existing rows for (k=0; k<numpp; k++) { if (ces1[k] != 0) { if (dec_ctx->row[k] != NULL) { assert(dec_ctx->row[k]->elem[0]); quotient = galois_divide(ces1[k], dec_ctx->row[k]->elem[0]); galois_multiply_add_region(&(ces1[k]), dec_ctx->row[k]->elem, quotient, dec_ctx->row[k]->len); galois_multiply_add_region(pkt->syms, dec_ctx->message[k], quotient, pktsize); dec_ctx->operations += 1 + dec_ctx->row[k]->len + pktsize; } else { // a valid pivot found, store it back to decoding matrix dec_ctx->row[k] = (struct row_vector*) malloc(sizeof(struct row_vector)); if (dec_ctx->row[k] == NULL) fprintf(stderr, "%s: malloc dec_ctx->row[%d] failed\n", fname, k); int len = numpp - k; dec_ctx->row[k]->len = len; dec_ctx->row[k]->elem = (GF_ELEMENT *) calloc(len, sizeof(GF_ELEMENT)); if (dec_ctx->row[k]->elem == NULL) fprintf(stderr, "%s: calloc dec_ctx->row[%d]->elem failed\n", fname, k); memcpy(dec_ctx->row[k]->elem, &(ces1[k]), len*sizeof(GF_ELEMENT)); assert(dec_ctx->row[k]->elem[0]); memcpy(dec_ctx->message[k], pkt->syms, pktsize*sizeof(GF_ELEMENT)); dec_ctx->pivots += 1; break; } } } free(ces1); if (dec_ctx->pivots == numpp) { dec_ctx->stage = FINALBACKWARD; finish_recovering_PP(dec_ctx); } return; } if (dec_ctx->stage == FORWARD && dec_ctx->pivots == dec_ctx->sc->snum) { // Attempt final forward substitution dec_ctx->stage = FINALFORWARD; dec_ctx->pivots = numpp - gensize; // reset number of pivots before we verify the bottom rows // Transform the bottom wrap-around vectors to full length (numpp) and then process against their above band vectors // Copy the corresponding part of the message matrix as well GF_ELEMENT **ces = calloc(gensize, sizeof(GF_ELEMENT*)); GF_ELEMENT **message = calloc(gensize, sizeof(GF_ELEMENT*)); for (i=0; i<gensize; i++) { ces[i] = calloc(numpp, sizeof(GF_ELEMENT)); if (ces[i] == NULL) fprintf(stderr, "%s: calloc ces failed\n", fname); for (j=0; j<dec_ctx->row[numpp-gensize+i]->len; j++) { int index = (numpp - gensize + i + j) % numpp; ces[i][index] = dec_ctx->row[numpp-gensize+i]->elem[j]; } message[i] = calloc(pktsize, sizeof(GF_ELEMENT)); memcpy(message[i], dec_ctx->message[numpp-gensize+i], pktsize*sizeof(GF_ELEMENT)); // free the rows in dec_ctx->row, and message free(dec_ctx->row[numpp-gensize+i]->elem); free(dec_ctx->row[numpp-gensize+i]); dec_ctx->row[numpp-gensize+i] = NULL; memset(dec_ctx->message[numpp-gensize+i], 0, sizeof(GF_ELEMENT)*pktsize); } // Process one by one against above band vectors for (i=0; i<gensize; i++) { // Process the full-length row against above band vectors for (k=0; k<numpp; k++) { if (ces[i][k] != 0) { if (dec_ctx->row[k] != NULL) { assert(dec_ctx->row[k]->elem[0]); quotient = galois_divide(ces[i][k], dec_ctx->row[k]->elem[0]); galois_multiply_add_region(&(ces[i][k]), dec_ctx->row[k]->elem, quotient, dec_ctx->row[k]->len); galois_multiply_add_region(message[i], dec_ctx->message[k], quotient, pktsize); dec_ctx->operations += 1 + dec_ctx->row[k]->len + pktsize; } else { // a valid pivot found, store it back to decoding matrix dec_ctx->row[k] = (struct row_vector*) malloc(sizeof(struct row_vector)); if (dec_ctx->row[k] == NULL) fprintf(stderr, "%s: malloc dec_ctx->row[%d] failed\n", fname, k); int len = numpp - k; dec_ctx->row[k]->len = len; dec_ctx->row[k]->elem = (GF_ELEMENT *) calloc(len, sizeof(GF_ELEMENT)); if (dec_ctx->row[k]->elem == NULL) fprintf(stderr, "%s: calloc dec_ctx->row[%d]->elem failed\n", fname, k); memcpy(dec_ctx->row[k]->elem, &(ces[i][k]), len*sizeof(GF_ELEMENT)); assert(dec_ctx->row[k]->elem[0]); memcpy(dec_ctx->message[k], message[i], pktsize*sizeof(GF_ELEMENT)); dec_ctx->pivots += 1; break; } } } free(ces[i]); // free the processed full-length vector free(message[i]); } // free ces, and message free(ces); free(message); // this is just an array of pointers } if (dec_ctx->pivots == numpp) { dec_ctx->stage = FINALBACKWARD; finish_recovering_PP(dec_ctx); } return; }