1 #include "cado.h" // IWYU pragma: keep
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <gmp.h>
5 #include <string.h>
6 #include "macros.h"
7
8 static void
printVec(int * vec,int ncols)9 printVec (int *vec, int ncols)
10 {
11 int i;
12
13 fprintf(stderr, "vec=");
14 for(i = 0; i < ncols; i++)
15 fprintf(stderr, "%d", vec[i] & 1);
16 fprintf(stderr, "\n");
17 }
18
19 static int
checkSparse(FILE * matfile,FILE * kerfile,int ncols,int nlimbs,int * vec,int compact,int verbose)20 checkSparse (FILE *matfile, FILE *kerfile, int ncols, int nlimbs, int *vec,
21 int compact, int verbose)
22 {
23 long a;
24 unsigned long w, b;
25 int i, j, ret = 0, nc, cc, jj;
26
27 memset(vec, 0, ncols * sizeof(int));
28 // get next dependence relation
29 rewind(matfile);
30 ret = fscanf(matfile, "%d %d", &i, &j);
31 ASSERT_ALWAYS(ret == 2);
32 for(int c ; c = getc(matfile), c != EOF && c != 'n' ; );
33 for(i = 0; i < nlimbs; ++i){
34 ret = fscanf(kerfile, "%lx", &w);
35 if(ret == -1)
36 break;
37 ASSERT_ALWAYS (ret == 1);
38 if(verbose)
39 fprintf(stderr, "w=%lx\n", w);
40 for(j = 0; j < GMP_NUMB_BITS; ++j){
41 if(w & 1UL){
42 if(verbose)
43 fprintf(stderr, "+R_%d\n", (i * GMP_NUMB_BITS)+j);
44 if(compact == 0) {
45 ret = fscanf(matfile, "%ld %lu %d", &a, &b, &nc);
46 ASSERT_ALWAYS(ret == 3);
47 } else {
48 ret = fscanf(matfile, "%d", &nc);
49 ASSERT_ALWAYS(ret == 1);
50 }
51 for(jj = 0; jj < nc; jj++){
52 ret = fscanf(matfile, "%d", &cc);
53 ASSERT_ALWAYS(ret == 1);
54 if(verbose >= 2)
55 fprintf(stderr, "vec[%d]++\n", cc);
56 if(cc >= ncols){
57 fprintf(stderr, "GASP: cc=%d > ncols=%d", cc, ncols);
58 fprintf(stderr, " at line %d\n", (i*GMP_NUMB_BITS)+j);
59 }
60 vec[cc]++;
61 }
62 if(verbose >= 2)
63 printVec(vec, ncols);
64 for(int c ; c = getc(matfile), c != EOF && c != 'n' ; );
65 }
66 else{
67 for(int c ; c = getc(matfile), c != EOF && c != 'n' ; );
68 }
69 w >>= 1;
70 }
71 }
72 return ret;
73 }
74
75 static void
checkVector(int * vec,int ncols,int skip)76 checkVector (int *vec, int ncols, int skip)
77 {
78 int ok, i;
79
80 ok = 1;
81 for(i = skip; i < ncols; i++)
82 if(vec[i] & 1){
83 ok = 0;
84 break;
85 }
86 if(ok)
87 fprintf(stderr, "y");
88 else
89 fprintf(stderr, "[n (%d)]", i);
90 }
91
92 static void
checkSparseAll(char * matname,char * kername,int compact,int skip,int verbose)93 checkSparseAll (char *matname, char *kername, int compact, int skip, int verbose)
94 {
95 FILE *matfile, *kerfile;
96 int nrows, ncols, nlimbs, *vec, ndep, ret;
97
98 matfile = fopen(matname, "r");
99 kerfile = fopen(kername, "r");
100 ret = fscanf(matfile, "%d %d", &nrows, &ncols);
101 ASSERT_ALWAYS(ret == 2);
102 nlimbs = (nrows / GMP_NUMB_BITS) + 1;
103 vec = (int *)malloc(ncols * sizeof(int));
104 ndep = 0;
105 while(1){
106 if(verbose)
107 fprintf(stderr, "Checking dep %d\n", ndep++);
108 ret = checkSparse(matfile,kerfile,ncols,nlimbs,vec,compact,verbose);
109 if(ret == -1)
110 break;
111 if(verbose >= 2)
112 printVec(vec, ncols);
113 checkVector(vec, ncols, skip);
114 }
115 fprintf(stderr, "\n");
116 free(vec);
117 fclose(matfile);
118 fclose(kerfile);
119 }
120
121 static int
checkWithIndex(FILE * purgedfile,FILE * indexfile,FILE * kerfile,int verbose,int nrows,int ncols,int small_nrows,int * vec)122 checkWithIndex (FILE *purgedfile, FILE *indexfile, FILE *kerfile, int verbose,
123 int nrows, int ncols, int small_nrows, int *vec)
124 {
125 unsigned long w;
126 int i, j, k, ret, nlimbs, ind, nrel, r, nc;
127 char *small_row_used, *rel_used;
128
129 nlimbs = (small_nrows / GMP_NUMB_BITS) + 1;
130 // first read used rows in the sparse matrix
131 small_row_used = (char *)malloc(small_nrows * sizeof(char));
132 memset(small_row_used, 0, small_nrows * sizeof(char));
133 for(i = 0; i < nlimbs; ++i){
134 ret = fscanf(kerfile, "%lx", &w);
135 if(ret == -1){
136 free(small_row_used);
137 return ret;
138 }
139 ASSERT_ALWAYS (ret == 1);
140 if(verbose)
141 fprintf(stderr, "w=%lx\n", w);
142 for(j = 0; j < GMP_NUMB_BITS; ++j){
143 if(w & 1UL){
144 ind = (i * GMP_NUMB_BITS)+j;
145 if(verbose)
146 fprintf(stderr, "+R_%d\n", ind);
147 small_row_used[ind] = 1;
148 }
149 w >>= 1;
150 }
151 }
152 // now map to the rels of the big matrix
153 rel_used = (char *)malloc(nrows * sizeof(char));
154 memset(rel_used, 0, nrows * sizeof(char));
155 rewind(indexfile);
156 ret = fscanf(indexfile, "%d %d", &i, &j); // skip first line
157 ASSERT_ALWAYS(ret == 2);
158 for(i = 0; i < small_nrows; i++){
159 ret = fscanf(indexfile, "%d", &nrel);
160 ASSERT_ALWAYS(ret == 1);
161 for(j = 0; j < nrel; j++){
162 ret = fscanf(indexfile, "%d", &r);
163 ASSERT_ALWAYS(ret == 2);
164 if(small_row_used[i])
165 rel_used[r] ^= 1;
166 }
167 }
168 // now really read the big matrix in
169 rewind(purgedfile);
170 ret = fscanf(purgedfile, "%d %d", &i, &j);
171 ASSERT_ALWAYS(ret == 2);
172 memset(vec, 0, ncols * sizeof(int));
173 for(i = 0; i < nrows; i++){
174 ret = fscanf(purgedfile, "%d %d", &j, &nc);
175 ASSERT_ALWAYS(ret == 2);
176 for(j = 0; j < nc; j++){
177 ret = fscanf(purgedfile, "%d", &k);
178 ASSERT_ALWAYS(ret == 1);
179 if(rel_used[i])
180 vec[k]++;
181 }
182 }
183 free(small_row_used);
184 free(rel_used);
185 return 1;
186 }
187
188 static void
checkWithIndexAll(char * purgedname,char * indexname,char * kername,int skip,int verbose)189 checkWithIndexAll (char *purgedname, char *indexname, char *kername,
190 int skip, int verbose)
191 {
192 FILE *purgedfile = fopen(purgedname, "r");
193 FILE *indexfile = fopen(indexname, "r");
194 FILE *kerfile = fopen(kername, "r");
195 int nrows, ncols, *vec, small_nrows, small_ncols, ret, ndep;
196
197 ret = fscanf(purgedfile, "%d %d", &nrows, &ncols);
198 ASSERT_ALWAYS(ret == 2);
199 ret = fscanf(indexfile, "%d %d", &small_nrows, &small_ncols);
200 ASSERT_ALWAYS(ret == 2);
201 vec = (int *)malloc(ncols * sizeof(int));
202 ndep = 0;
203 while(1){
204 if(verbose)
205 fprintf(stderr, "Checking dep %d\n", ndep++);
206 ret = checkWithIndex(purgedfile,indexfile,kerfile,verbose,nrows,ncols,small_nrows, vec);
207 if(ret == -1)
208 break;
209 checkVector(vec, ncols, skip);
210 }
211 fprintf(stderr, "\n");
212 free(vec);
213 fclose(kerfile);
214 fclose(purgedfile);
215 fclose(indexfile);
216 }
217
218 static void
usage(void)219 usage (void)
220 {
221 fprintf (stderr, "Usage: checkdep [-verbose] [-skip n] -purged file -index file -ker file\n");
222 fprintf (stderr, " checkdep [-verbose] [-compact] [-skip n] -mat file -ker file\n");
223 exit (1);
224 }
225
226 int
main(int argc,char * argv[])227 main (int argc, char *argv[])
228 {
229 char *matname = NULL, *indexname = NULL, *purgedname = NULL;
230 char *kername = NULL;
231 int verbose = 0, compact = 0, skip = 0;
232
233 while(argc > 1 && argv[1][0] == '-'){
234 if(argc > 2 && strcmp (argv[1], "-mat") == 0){
235 matname = argv[2];
236 argc -= 2;
237 argv += 2;
238 }
239 else if(argc > 2 && strcmp (argv[1], "-ker") == 0){
240 kername = argv[2];
241 argc -= 2;
242 argv += 2;
243 }
244 else if(argc > 2 && strcmp (argv[1], "-index") == 0){
245 indexname = argv[2];
246 argc -= 2;
247 argv += 2;
248 }
249 else if(argc > 2 && strcmp (argv[1], "-purged") == 0){
250 purgedname = argv[2];
251 argc -= 2;
252 argv += 2;
253 }
254 else if(argc > 2 && strcmp (argv[1], "-skip") == 0){
255 skip = atoi(argv[2]);
256 argc -= 2;
257 argv += 2;
258 }
259 else if(argc > 1 && strcmp (argv[1], "-compact") == 0){
260 compact = 1;
261 argc -= 1;
262 argv += 1;
263 }
264 else if(argc > 1 && strcmp (argv[1], "-verbose") == 0){
265 verbose = 1;
266 argc -= 1;
267 argv += 1;
268 }
269 }
270
271 if (indexname != NULL)
272 {
273 if (purgedname == NULL || kername == NULL)
274 usage ();
275 checkWithIndexAll (purgedname, indexname, kername, skip, verbose);
276 }
277 else
278 {
279 if (matname == NULL || kername == NULL)
280 usage ();
281 checkSparseAll (matname, kername, compact, skip, verbose);
282 }
283 return 0;
284 }
285