159 lines
4.8 KiB
C
159 lines
4.8 KiB
C
/******************************************************************************
|
|
*
|
|
* M4RI: Linear Algebra over GF(2)
|
|
*
|
|
* Copyright (C) 2011 Carlo Wood <carlo@alinoe.com>
|
|
*
|
|
* Distributed under the terms of the GNU General Public License (GPL)
|
|
* version 2 or higher.
|
|
*
|
|
* This code is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* The full text of the GPL is available at:
|
|
*
|
|
* http://www.gnu.org/licenses/
|
|
******************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "mzd.h"
|
|
#include "mzp.h"
|
|
|
|
#if __M4RI_DEBUG_DUMP
|
|
|
|
static unsigned long dd_sequence_number = 0;
|
|
|
|
static void entry(char const* function, char const* file, int line)
|
|
{
|
|
#if !__M4RI_DD_QUIET
|
|
printf("Sequence#: %ld; %s @ %s:%d; ", dd_sequence_number, function, file, line);
|
|
#endif
|
|
++dd_sequence_number;
|
|
}
|
|
|
|
static inline void consistency_check_row(mzd_t const *M, rci_t row)
|
|
{
|
|
assert(row >= 0 && row < M->nrows);
|
|
assert(M->rows[row] == mzd_row(M, row));
|
|
if (mzd_is_windowed(M))
|
|
return;
|
|
// Check that the excess bits are zero.
|
|
assert((M->rows[row][M->width - 1] & ~M->high_bitmask) == 0);
|
|
// Check that the padding bits are zero, if any.
|
|
assert(M->width == M->rowstride || M->rows[row][M->width] == 0);
|
|
}
|
|
|
|
static void consistency_check(mzd_t const *M)
|
|
{
|
|
assert(M->nrows >= 0 && M->ncols >= 0);
|
|
assert(M->width * m4ri_radix >= M->ncols);
|
|
assert((M->width - 1) * m4ri_radix < M->ncols);
|
|
assert(M->width < mzd_paddingwidth || (M->rowstride & 1) == 0);
|
|
//assert((M->blockrows_mask + 1) == (1 << M->blockrows_log));
|
|
assert((1 << M->blockrows_log) * M->rowstride <= __M4RI_MAX_MZD_BLOCKSIZE);
|
|
assert((1 << M->blockrows_log) * M->rowstride > __M4RI_MAX_MZD_BLOCKSIZE / 2);
|
|
assert((M->width > 1 && M->high_bitmask == __M4RI_LEFT_BITMASK((M->ncols) % m4ri_radix)) ||
|
|
(M->width < 2 && M->high_bitmask == __M4RI_MIDDLE_BITMASK(M->ncols, 0)));
|
|
assert(((M->flags & mzd_flag_nonzero_excess) == 0) == ((M->ncols % m4ri_radix == 0)));
|
|
assert((M->flags & mzd_flag_windowed_zeroexcess) == 0 || ((M->ncols) % m4ri_radix == 0));
|
|
assert((((M->flags & mzd_flag_multiple_blocks) == 0) == (mzd_row_to_block(M, M->nrows - 1) == 0)));
|
|
int n = 0;
|
|
rci_t counted = 0;
|
|
word* ptr = mzd_first_row(M);
|
|
int row_count = mzd_rows_in_block(M, 0);
|
|
while(1) {
|
|
while (row_count--) {
|
|
assert(ptr == M->rows[counted++]);
|
|
ptr += M->rowstride;
|
|
}
|
|
++n;
|
|
row_count = mzd_rows_in_block(M, n);
|
|
if (row_count <= 0)
|
|
break;
|
|
ptr = mzd_first_row_next_block(M, n);
|
|
}
|
|
assert(M->ncols == 0 || counted == M->nrows);
|
|
if (mzd_is_windowed(M))
|
|
return;
|
|
assert(M->rowstride == M->width || (M->rowstride == M->width + 1 && M->width >= mzd_paddingwidth));
|
|
for (rci_t r = 0; r < M->nrows; ++r) {
|
|
consistency_check_row(M, r);
|
|
}
|
|
}
|
|
|
|
void m4ri_dd_int(char const* function, char const* file, int line, int i)
|
|
{
|
|
entry(function, file, line);
|
|
#if !__M4RI_DD_QUIET
|
|
printf("int: %d\n", i);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_rci(char const* function, char const* file, int line, rci_t rci)
|
|
{
|
|
entry(function, file, line);
|
|
#if !__M4RI_DD_QUIET
|
|
printf("rci: %d\n", rci);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_rci_array(char const* function, char const* file, int line, rci_t *rciptr, int len)
|
|
{
|
|
entry(function, file, line);
|
|
#if !__M4RI_DD_QUIET
|
|
word hash = 0;
|
|
for (int i = 0; i < len; ++i)
|
|
hash ^= rotate_word(rciptr[i], i % m4ri_radix);
|
|
printf("rci array (size %d) hash: %llx\n", len, hash);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_rawrow(char const* function, char const* file, int line, word const* rowptr, wi_t wide)
|
|
{
|
|
entry(function, file, line);
|
|
#if !__M4RI_DD_QUIET
|
|
word hash = calculate_hash(rowptr, wide);
|
|
printf("raw row (%d words) hash: %llx\n", wide, hash);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_row(char const* function, char const* file, int line, mzd_t const* M, rci_t row)
|
|
{
|
|
entry(function, file, line);
|
|
consistency_check_row(M, row);
|
|
#if !__M4RI_DD_QUIET
|
|
word hash = calculate_hash(M->rows[row], M->width);
|
|
printf("row %d hash: %llx\n", row, hash);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_mzd(char const* function, char const* file, int line, mzd_t const* M)
|
|
{
|
|
entry(function, file, line);
|
|
consistency_check(M);
|
|
#if !__M4RI_DD_QUIET
|
|
word hash = 0;
|
|
for (rci_t r = 0; r < M->nrows; ++r)
|
|
hash ^= rotate_word(calculate_hash(M->rows[r], M->width), r % m4ri_radix);
|
|
printf("mzd hash: %llx\n", hash);
|
|
#endif
|
|
}
|
|
|
|
void m4ri_dd_mzp(char const* function, char const* file, int line, mzp_t const* P)
|
|
{
|
|
entry(function, file, line);
|
|
#if !__M4RI_DD_QUIET
|
|
word hash = 0;
|
|
for (rci_t i = 0; i < P->length; ++i)
|
|
hash ^= rotate_word(P->values[i], i % m4ri_radix);
|
|
printf("mzp hash: %llx\n", hash);
|
|
#endif
|
|
}
|
|
|
|
#endif
|