1 /******************************************************************************
2 *
3 *            M4RI: Linear Algebra over GF(2)
4 *
5 *    Copyright (C) 2011 Carlo Wood <carlo@alinoe.com>
6 *
7 *  Distributed under the terms of the GNU General Public License (GPL)
8 *  version 2 or higher.
9 *
10 *    This code is distributed in the hope that it will be useful,
11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *    General Public License for more details.
14 *
15 *  The full text of the GPL is available at:
16 *
17 *                  http://www.gnu.org/licenses/
18 ******************************************************************************/
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "mzd.h"
25 #include "mzp.h"
26 
27 #if __M4RI_DEBUG_DUMP
28 
29 static unsigned long dd_sequence_number = 0;
30 
entry(char const * function,char const * file,int line)31 static void entry(char const* function, char const* file, int line)
32 {
33 #if !__M4RI_DD_QUIET
34   printf("Sequence#: %ld; %s @ %s:%d; ", dd_sequence_number, function, file, line);
35 #endif
36   ++dd_sequence_number;
37 }
38 
consistency_check_row(mzd_t const * M,rci_t row)39 static inline void consistency_check_row(mzd_t const *M, rci_t row)
40 {
41   assert(row >= 0 && row < M->nrows);
42   assert(M->rows[row] == mzd_row(M, row));
43   if (mzd_is_windowed(M))
44     return;
45   // Check that the excess bits are zero.
46   assert((M->rows[row][M->width - 1] & ~M->high_bitmask) == 0);
47   // Check that the padding bits are zero, if any.
48   assert(M->width == M->rowstride || M->rows[row][M->width] == 0);
49 }
50 
consistency_check(mzd_t const * M)51 static void consistency_check(mzd_t const *M)
52 {
53   assert(M->nrows >= 0 && M->ncols >= 0);
54   assert(M->width * m4ri_radix >= M->ncols);
55   assert((M->width - 1) * m4ri_radix < M->ncols);
56   assert(M->width < mzd_paddingwidth || (M->rowstride & 1) == 0);
57   //assert((M->blockrows_mask + 1) == (1 << M->blockrows_log));
58   assert((1 << M->blockrows_log) * M->rowstride <= __M4RI_MAX_MZD_BLOCKSIZE);
59   assert((1 << M->blockrows_log) * M->rowstride > __M4RI_MAX_MZD_BLOCKSIZE / 2);
60   assert((M->width > 1 && M->high_bitmask == __M4RI_LEFT_BITMASK((M->ncols) % m4ri_radix)) ||
61          (M->width < 2 && M->high_bitmask == __M4RI_MIDDLE_BITMASK(M->ncols, 0)));
62   assert(((M->flags & mzd_flag_nonzero_excess) == 0) == ((M->ncols % m4ri_radix == 0)));
63   assert((M->flags & mzd_flag_windowed_zeroexcess) == 0 || ((M->ncols) % m4ri_radix == 0));
64   assert((((M->flags & mzd_flag_multiple_blocks) == 0) == (mzd_row_to_block(M, M->nrows - 1) == 0)));
65   int n = 0;
66   rci_t counted = 0;
67   word* ptr = mzd_first_row(M);
68   int row_count = mzd_rows_in_block(M, 0);
69   while(1) {
70     while (row_count--) {
71       assert(ptr == M->rows[counted++]);
72       ptr += M->rowstride;
73     }
74     ++n;
75     row_count = mzd_rows_in_block(M, n);
76     if (row_count <= 0)
77       break;
78     ptr = mzd_first_row_next_block(M, n);
79   }
80   assert(M->ncols == 0 || counted == M->nrows);
81   if (mzd_is_windowed(M))
82     return;
83   assert(M->rowstride == M->width || (M->rowstride == M->width + 1 && M->width >= mzd_paddingwidth));
84   for (rci_t r = 0; r < M->nrows; ++r) {
85     consistency_check_row(M, r);
86   }
87 }
88 
m4ri_dd_int(char const * function,char const * file,int line,int i)89 void m4ri_dd_int(char const* function, char const* file, int line, int i)
90 {
91   entry(function, file, line);
92 #if !__M4RI_DD_QUIET
93   printf("int: %d\n", i);
94 #endif
95 }
96 
m4ri_dd_rci(char const * function,char const * file,int line,rci_t rci)97 void m4ri_dd_rci(char const* function, char const* file, int line, rci_t rci)
98 {
99   entry(function, file, line);
100 #if !__M4RI_DD_QUIET
101   printf("rci: %d\n", rci);
102 #endif
103 }
104 
m4ri_dd_rci_array(char const * function,char const * file,int line,rci_t * rciptr,int len)105 void m4ri_dd_rci_array(char const* function, char const* file, int line, rci_t *rciptr, int len)
106 {
107   entry(function, file, line);
108 #if !__M4RI_DD_QUIET
109   word hash = 0;
110   for (int i = 0; i < len; ++i)
111     hash ^= rotate_word(rciptr[i], i % m4ri_radix);
112   printf("rci array (size %d) hash: %llx\n", len, hash);
113 #endif
114 }
115 
m4ri_dd_rawrow(char const * function,char const * file,int line,word const * rowptr,wi_t wide)116 void m4ri_dd_rawrow(char const* function, char const* file, int line, word const* rowptr, wi_t wide)
117 {
118   entry(function, file, line);
119 #if !__M4RI_DD_QUIET
120   word hash = calculate_hash(rowptr, wide);
121   printf("raw row (%d words) hash: %llx\n", wide, hash);
122 #endif
123 }
124 
m4ri_dd_row(char const * function,char const * file,int line,mzd_t const * M,rci_t row)125 void m4ri_dd_row(char const* function, char const* file, int line, mzd_t const* M, rci_t row)
126 {
127   entry(function, file, line);
128   consistency_check_row(M, row);
129 #if !__M4RI_DD_QUIET
130   word hash = calculate_hash(M->rows[row], M->width);
131   printf("row %d hash: %llx\n", row, hash);
132 #endif
133 }
134 
m4ri_dd_mzd(char const * function,char const * file,int line,mzd_t const * M)135 void m4ri_dd_mzd(char const* function, char const* file, int line, mzd_t const* M)
136 {
137   entry(function, file, line);
138   consistency_check(M);
139 #if !__M4RI_DD_QUIET
140   word hash = 0;
141   for (rci_t r = 0; r < M->nrows; ++r)
142     hash ^= rotate_word(calculate_hash(M->rows[r], M->width), r % m4ri_radix);
143   printf("mzd hash: %llx\n", hash);
144 #endif
145 }
146 
m4ri_dd_mzp(char const * function,char const * file,int line,mzp_t const * P)147 void m4ri_dd_mzp(char const* function, char const* file, int line, mzp_t const* P)
148 {
149   entry(function, file, line);
150 #if !__M4RI_DD_QUIET
151   word hash = 0;
152   for (rci_t i = 0; i < P->length; ++i)
153     hash ^= rotate_word(P->values[i], i % m4ri_radix);
154   printf("mzp hash: %llx\n", hash);
155 #endif
156 }
157 
158 #endif
159