thefinalboss commited on
Commit
c64d96e
·
verified ·
1 Parent(s): 4cfd2c0

v3_scale/checker: recompte dédup 64 o corpus_diverse_v1 (REPORT, agrégats assainis sans plages ni texte, dedup64_div1.py 5230e995, run.sh) — raw 186812/687/231506 ; norm 149315/454/221174

Browse files
v3_scale/checker/recount/corpus_diverse_v1_dedup/REPORT.md ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Checker — recompte dedup 64-grammes corpus_diverse_v1 (agrégats)
2
+
3
+ Rapport reconstitué le 30 oct. 2026 (Toronto) à partir des seuls JSON d'agrégats (le REPORT.md d'origine est absent du disque après la restauration de la boîte). Aucune position, masque, extrait de texte ni donnée d'éval n'est publié.
4
+
5
+ - train : corpus_diverse_v1/train.bin, 530,137,703 o, sha256 c813244c… (ok=True)
6
+ - script dedup64_div1.py sha256 5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428 ; k=64 ; Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet
7
+
8
+ | forme | positions train appariées | plages fusionnées | octets dans plages | faux positifs hash | positions seg multilang |
9
+ |---|---|---|---|---|---|
10
+ | brut | 186,812 | 687 | 231,506 | 0 | 0 |
11
+ | normalisé | 149,315 | 454 | 221,174 | 0 | 117 |
12
+
13
+ Normalisation : suppr. \r ; A-Z->a-z ASCII ; suites [ \t\n\v\f] -> 1 espace ; en flux
14
+
15
+ | fenêtre | n64 brut | trouvés brut | octets éval couverts brut | n64 norm | trouvés norm | octets couverts norm |
16
+ |---|---|---|---|---|---|---|
17
+ | test20k_old | 319,877 | 1,405 | 4,263 | 298,660 | 1,915 | 3,944 |
18
+ | fc2 | 199,729 | 0 | 0 | 157,783 | 22 | 113 |
19
+ | fresh_en | 119,700 | 0 | 0 | 119,587 | 0 | 0 |
20
+ | fresh_fr | 1,088,625 | 0 | 0 | 1,067,982 | 77 | 143 |
21
+ | test_v3 | 3,486,590 | 0 | 0 | 3,390,446 | 17 | 149 |
22
+ | queries | 27,737 | 0 | 0 | 27,688 | 0 | 0 |
23
+ | bg1_test | 894,655 | 33,766 | 45,852 | 823,920 | 26,765 | 42,756 |
24
+
25
+ Autotests (selftest.json) : ALL_PASS = True.
26
+ Détails complets : dedup64_aggregates.json.
v3_scale/checker/recount/corpus_diverse_v1_dedup/dedup64_aggregates.json ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "what": "Checker — dedup 64-grammes corpus_diverse_v1/train.bin vs fenêtres d'éval — AGRÉGATS ASSAINIS (échantillons de plages train retirés, sans texte, sans masques)",
3
+ "source_json_sha256": {
4
+ "dedup64_raw.json": "ef939f41937bd18536fa0aff33b97a47fa3c8c0b16caec2daf8bfbb9302b3d52",
5
+ "dedup64_norm.json": "b73e5099ccad14ee4fb1c80c06904601ab50f5ced0160ca4aaade0d199189fa0"
6
+ },
7
+ "raw": {
8
+ "form": "raw",
9
+ "k": 64,
10
+ "hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
11
+ "normalisation": null,
12
+ "train": "/workspace/spira_shared/corpus_diverse_v1/train.bin",
13
+ "train_bytes": 530137703,
14
+ "train_sha256": "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9",
15
+ "train_sha_ok": true,
16
+ "train_64gram_positions_hashed": 530137640,
17
+ "table_unique_hashes": 5777106,
18
+ "table_internal_collisions": 0,
19
+ "candidates": 186812,
20
+ "hash_false_positives_rejected": 0,
21
+ "train_positions_matched_any": 186812,
22
+ "train_ranges_merged_any": 687,
23
+ "train_bytes_in_ranges_any": 231506,
24
+ "train_positions_seg_multilang_any": 0,
25
+ "windows": {
26
+ "test20k_old": {
27
+ "n64": 319877,
28
+ "n64_found": 1405,
29
+ "frac64_found": 0.004392313295422928,
30
+ "n64_distinct_found": 1386,
31
+ "eval_bytes": 319940,
32
+ "eval_bytes_covered": 4263,
33
+ "eval_bytes_excl_ctx64": 6596,
34
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
35
+ "train_positions_matched": 13111,
36
+ "train_positions_seg_bg1": 13111,
37
+ "train_positions_seg_multilang": 0,
38
+ "train_ranges_merged": 133,
39
+ "train_bytes_in_ranges": 22280,
40
+ "xcheck_mask_2134": {
41
+ "key": "m7_test20k",
42
+ "mask_covered": 4263,
43
+ "mask_excl": 6596,
44
+ "covered_identical_to_mask": true,
45
+ "covered_outside_mask_excl": 0,
46
+ "excl_identical_to_mask": true
47
+ }
48
+ },
49
+ "fc2": {
50
+ "n64": 199729,
51
+ "n64_found": 0,
52
+ "frac64_found": 0.0,
53
+ "n64_distinct_found": 0,
54
+ "eval_bytes": 199792,
55
+ "eval_bytes_covered": 0,
56
+ "eval_bytes_excl_ctx64": 0,
57
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
58
+ "train_positions_matched": 0,
59
+ "train_positions_seg_bg1": 0,
60
+ "train_positions_seg_multilang": 0,
61
+ "train_ranges_merged": 0,
62
+ "train_bytes_in_ranges": 0,
63
+ "xcheck_mask_2134": {
64
+ "key": "bench_fc2",
65
+ "mask_covered": 0,
66
+ "mask_excl": 0,
67
+ "covered_identical_to_mask": true,
68
+ "covered_outside_mask_excl": 0,
69
+ "excl_identical_to_mask": true
70
+ }
71
+ },
72
+ "fresh_en": {
73
+ "n64": 119700,
74
+ "n64_found": 0,
75
+ "frac64_found": 0.0,
76
+ "n64_distinct_found": 0,
77
+ "eval_bytes": 119763,
78
+ "eval_bytes_covered": 0,
79
+ "eval_bytes_excl_ctx64": 0,
80
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
81
+ "train_positions_matched": 0,
82
+ "train_positions_seg_bg1": 0,
83
+ "train_positions_seg_multilang": 0,
84
+ "train_ranges_merged": 0,
85
+ "train_bytes_in_ranges": 0,
86
+ "xcheck_mask_2134": {
87
+ "key": "bench_fresh_en",
88
+ "mask_covered": 0,
89
+ "mask_excl": 0,
90
+ "covered_identical_to_mask": true,
91
+ "covered_outside_mask_excl": 0,
92
+ "excl_identical_to_mask": true
93
+ }
94
+ },
95
+ "fresh_fr": {
96
+ "n64": 1088625,
97
+ "n64_found": 0,
98
+ "frac64_found": 0.0,
99
+ "n64_distinct_found": 0,
100
+ "eval_bytes": 1088688,
101
+ "eval_bytes_covered": 0,
102
+ "eval_bytes_excl_ctx64": 0,
103
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
104
+ "train_positions_matched": 0,
105
+ "train_positions_seg_bg1": 0,
106
+ "train_positions_seg_multilang": 0,
107
+ "train_ranges_merged": 0,
108
+ "train_bytes_in_ranges": 0,
109
+ "xcheck_mask_2134": {
110
+ "key": "bench_fresh_fr",
111
+ "mask_covered": 0,
112
+ "mask_excl": 0,
113
+ "covered_identical_to_mask": true,
114
+ "covered_outside_mask_excl": 0,
115
+ "excl_identical_to_mask": true
116
+ }
117
+ },
118
+ "test_v3": {
119
+ "n64": 3486590,
120
+ "n64_found": 0,
121
+ "frac64_found": 0.0,
122
+ "n64_distinct_found": 0,
123
+ "eval_bytes": 3486653,
124
+ "eval_bytes_covered": 0,
125
+ "eval_bytes_excl_ctx64": 0,
126
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
127
+ "train_positions_matched": 0,
128
+ "train_positions_seg_bg1": 0,
129
+ "train_positions_seg_multilang": 0,
130
+ "train_ranges_merged": 0,
131
+ "train_bytes_in_ranges": 0,
132
+ "xcheck_mask_2134": {
133
+ "key": "bench_test_v3",
134
+ "mask_covered": 0,
135
+ "mask_excl": 0,
136
+ "covered_identical_to_mask": true,
137
+ "covered_outside_mask_excl": 0,
138
+ "excl_identical_to_mask": true
139
+ }
140
+ },
141
+ "queries": {
142
+ "n64": 27737,
143
+ "n64_found": 0,
144
+ "frac64_found": 0.0,
145
+ "n64_distinct_found": 0,
146
+ "eval_bytes": 27800,
147
+ "eval_bytes_covered": 0,
148
+ "eval_bytes_excl_ctx64": 0,
149
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
150
+ "train_positions_matched": 0,
151
+ "train_positions_seg_bg1": 0,
152
+ "train_positions_seg_multilang": 0,
153
+ "train_ranges_merged": 0,
154
+ "train_bytes_in_ranges": 0,
155
+ "xcheck_mask_2134": {
156
+ "key": "bench_queries",
157
+ "mask_covered": 0,
158
+ "mask_excl": 0,
159
+ "covered_identical_to_mask": true,
160
+ "covered_outside_mask_excl": 0,
161
+ "excl_identical_to_mask": true
162
+ }
163
+ },
164
+ "bg1_test": {
165
+ "n64": 894655,
166
+ "n64_found": 33766,
167
+ "frac64_found": 0.03774192286412081,
168
+ "n64_distinct_found": 32879,
169
+ "eval_bytes": 894718,
170
+ "eval_bytes_covered": 45852,
171
+ "eval_bytes_excl_ctx64": 54828,
172
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
173
+ "train_positions_matched": 186809,
174
+ "train_positions_seg_bg1": 186809,
175
+ "train_positions_seg_multilang": 0,
176
+ "train_ranges_merged": 687,
177
+ "train_bytes_in_ranges": 231503,
178
+ "xcheck_mask_2134": {
179
+ "key": "broad_test_bin",
180
+ "mask_covered": 45852,
181
+ "mask_excl": 54828,
182
+ "covered_identical_to_mask": true,
183
+ "covered_outside_mask_excl": 0,
184
+ "excl_identical_to_mask": true
185
+ }
186
+ }
187
+ },
188
+ "files": {
189
+ "masks_raw.npz": "8f56c0edf25cafb368c1a2c848ec926fe389c6695863b37d5c5895b93350b7b0",
190
+ "train_ranges_raw.npz": "31115e29fee3d0f794a5357bce1e942b846ad491e91fecc14e566839ced220bc"
191
+ },
192
+ "elapsed_s": 74.0,
193
+ "peak_rss_kB": 217304,
194
+ "script_sha256": "5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428"
195
+ },
196
+ "norm": {
197
+ "form": "norm",
198
+ "k": 64,
199
+ "hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
200
+ "normalisation": "suppr. \\r ; A-Z->a-z ASCII ; suites [ \\t\\n\\v\\f] -> 1 espace ; en flux",
201
+ "train": "/workspace/spira_shared/corpus_diverse_v1/train.bin",
202
+ "train_bytes": 530137703,
203
+ "train_sha256": "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9",
204
+ "train_sha_ok": true,
205
+ "train_64gram_positions_hashed": 489807340,
206
+ "table_unique_hashes": 5551296,
207
+ "table_internal_collisions": 0,
208
+ "candidates": 149315,
209
+ "hash_false_positives_rejected": 0,
210
+ "train_positions_matched_any": 149315,
211
+ "train_ranges_merged_any": 454,
212
+ "train_bytes_in_ranges_any": 221174,
213
+ "train_positions_seg_multilang_any": 117,
214
+ "windows": {
215
+ "test20k_old": {
216
+ "n64": 298660,
217
+ "n64_found": 1915,
218
+ "frac64_found": 0.006411973481550927,
219
+ "n64_distinct_found": 1907,
220
+ "eval_bytes": 319940,
221
+ "eval_bytes_covered": 3944,
222
+ "eval_bytes_excl_ctx64": 5448,
223
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
224
+ "train_positions_matched": 12453,
225
+ "train_positions_seg_bg1": 12453,
226
+ "train_positions_seg_multilang": 0,
227
+ "train_ranges_merged": 54,
228
+ "train_bytes_in_ranges": 17298,
229
+ "xcheck_mask_2134": {
230
+ "key": "m7_test20k",
231
+ "mask_covered": 4263,
232
+ "mask_excl": 6596,
233
+ "covered_identical_to_mask": false,
234
+ "covered_outside_mask_excl": 647,
235
+ "excl_identical_to_mask": false
236
+ }
237
+ },
238
+ "fc2": {
239
+ "n64": 157783,
240
+ "n64_found": 22,
241
+ "frac64_found": 0.0001394320047153369,
242
+ "n64_distinct_found": 22,
243
+ "eval_bytes": 199792,
244
+ "eval_bytes_covered": 113,
245
+ "eval_bytes_excl_ctx64": 177,
246
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
247
+ "train_positions_matched": 122,
248
+ "train_positions_seg_bg1": 22,
249
+ "train_positions_seg_multilang": 100,
250
+ "train_ranges_merged": 6,
251
+ "train_bytes_in_ranges": 573,
252
+ "xcheck_mask_2134": {
253
+ "key": "bench_fc2",
254
+ "mask_covered": 0,
255
+ "mask_excl": 0,
256
+ "covered_identical_to_mask": false,
257
+ "covered_outside_mask_excl": 113,
258
+ "excl_identical_to_mask": false
259
+ }
260
+ },
261
+ "fresh_en": {
262
+ "n64": 119587,
263
+ "n64_found": 0,
264
+ "frac64_found": 0.0,
265
+ "n64_distinct_found": 0,
266
+ "eval_bytes": 119763,
267
+ "eval_bytes_covered": 0,
268
+ "eval_bytes_excl_ctx64": 0,
269
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
270
+ "train_positions_matched": 0,
271
+ "train_positions_seg_bg1": 0,
272
+ "train_positions_seg_multilang": 0,
273
+ "train_ranges_merged": 0,
274
+ "train_bytes_in_ranges": 0,
275
+ "xcheck_mask_2134": {
276
+ "key": "bench_fresh_en",
277
+ "mask_covered": 0,
278
+ "mask_excl": 0,
279
+ "covered_identical_to_mask": true,
280
+ "covered_outside_mask_excl": 0,
281
+ "excl_identical_to_mask": true
282
+ }
283
+ },
284
+ "fresh_fr": {
285
+ "n64": 1067982,
286
+ "n64_found": 77,
287
+ "frac64_found": 7.209859342198652e-05,
288
+ "n64_distinct_found": 77,
289
+ "eval_bytes": 1088688,
290
+ "eval_bytes_covered": 143,
291
+ "eval_bytes_excl_ctx64": 207,
292
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
293
+ "train_positions_matched": 1112,
294
+ "train_positions_seg_bg1": 1112,
295
+ "train_positions_seg_multilang": 0,
296
+ "train_ranges_merged": 18,
297
+ "train_bytes_in_ranges": 2270,
298
+ "xcheck_mask_2134": {
299
+ "key": "bench_fresh_fr",
300
+ "mask_covered": 0,
301
+ "mask_excl": 0,
302
+ "covered_identical_to_mask": false,
303
+ "covered_outside_mask_excl": 143,
304
+ "excl_identical_to_mask": false
305
+ }
306
+ },
307
+ "test_v3": {
308
+ "n64": 3390446,
309
+ "n64_found": 17,
310
+ "frac64_found": 5.014089591752825e-06,
311
+ "n64_distinct_found": 17,
312
+ "eval_bytes": 3486653,
313
+ "eval_bytes_covered": 149,
314
+ "eval_bytes_excl_ctx64": 277,
315
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
316
+ "train_positions_matched": 17,
317
+ "train_positions_seg_bg1": 17,
318
+ "train_positions_seg_multilang": 0,
319
+ "train_ranges_merged": 2,
320
+ "train_bytes_in_ranges": 144,
321
+ "xcheck_mask_2134": {
322
+ "key": "bench_test_v3",
323
+ "mask_covered": 0,
324
+ "mask_excl": 0,
325
+ "covered_identical_to_mask": false,
326
+ "covered_outside_mask_excl": 149,
327
+ "excl_identical_to_mask": false
328
+ }
329
+ },
330
+ "queries": {
331
+ "n64": 27688,
332
+ "n64_found": 0,
333
+ "frac64_found": 0.0,
334
+ "n64_distinct_found": 0,
335
+ "eval_bytes": 27800,
336
+ "eval_bytes_covered": 0,
337
+ "eval_bytes_excl_ctx64": 0,
338
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
339
+ "train_positions_matched": 0,
340
+ "train_positions_seg_bg1": 0,
341
+ "train_positions_seg_multilang": 0,
342
+ "train_ranges_merged": 0,
343
+ "train_bytes_in_ranges": 0,
344
+ "xcheck_mask_2134": {
345
+ "key": "bench_queries",
346
+ "mask_covered": 0,
347
+ "mask_excl": 0,
348
+ "covered_identical_to_mask": true,
349
+ "covered_outside_mask_excl": 0,
350
+ "excl_identical_to_mask": true
351
+ }
352
+ },
353
+ "bg1_test": {
354
+ "n64": 823920,
355
+ "n64_found": 26765,
356
+ "frac64_found": 0.03248494999514516,
357
+ "n64_distinct_found": 26046,
358
+ "eval_bytes": 894718,
359
+ "eval_bytes_covered": 42756,
360
+ "eval_bytes_excl_ctx64": 49727,
361
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
362
+ "train_positions_matched": 148061,
363
+ "train_positions_seg_bg1": 148044,
364
+ "train_positions_seg_multilang": 17,
365
+ "train_ranges_merged": 428,
366
+ "train_bytes_in_ranges": 218184,
367
+ "xcheck_mask_2134": {
368
+ "key": "broad_test_bin",
369
+ "mask_covered": 45852,
370
+ "mask_excl": 54828,
371
+ "covered_identical_to_mask": false,
372
+ "covered_outside_mask_excl": 1484,
373
+ "excl_identical_to_mask": false
374
+ }
375
+ }
376
+ },
377
+ "files": {
378
+ "masks_norm.npz": "7a3d76b5a20475a35dc0113efc0648d358df63f805eb05320affdf6f036df465",
379
+ "train_ranges_norm.npz": "e8cfddf83e1c2b0bace101d9a9a784f5e5ad1363c2aa4a1d365146b604cfb2a9"
380
+ },
381
+ "elapsed_s": 78.2,
382
+ "peak_rss_kB": 233784,
383
+ "script_sha256": "5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428"
384
+ }
385
+ }
v3_scale/checker/recount/corpus_diverse_v1_dedup/dedup64_div1.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """SPIRA Checker — 25 oct. 2026 (Toronto) — recompte INDÉPENDANT de dédup 64 o : corpus_diverse_v1/train.bin vs fenêtres d'éval.
3
+ Logique reprise de checker/recount/bg1_test_dedup64/dedup64.py (sha 4bee4293…) : Horner mod 2^64 (P = 0x9E3779B97F4A7C15) sur chaque
4
+ 64-gramme, table triée + np.searchsorted, train lu par blocs + 63 o de recouvrement, CONFIRMATION octet à octet de chaque candidat.
5
+ Deux formes (un processus par forme, pour tenir < 300 Mo RSS) :
6
+ raw : octets bruts ;
7
+ norm : \r supprimés, A-Z -> a-z (ASCII seulement), toute suite d'espaces (espace, \t, \n, \v, \f) -> un seul espace ; normalisation
8
+ en flux (état « dernier octet = espace » propagé entre blocs) ; chaque octet normalisé garde son offset d'origine.
9
+ Tous les débuts de 64-grammes des fenêtres sont hachés (les positions notées par le banc sont tirées par bench_common, non séparables
10
+ du fichier seul ; « tous » est un sur-ensemble). Ne lit que des fichiers ; écrit UNIQUEMENT dans son dossier. Aucun texte en sortie.
11
+ Usage : dedup64_div1.py raw|norm | dedup64_div1.py selftest"""
12
+ import sys, os, json, hashlib, time, resource
13
+ import numpy as np
14
+ S = "/workspace/spira_shared"; OD = os.path.dirname(os.path.abspath(__file__)); K = 64; P = np.uint64(0x9E3779B97F4A7C15)
15
+ TRAIN = f"{S}/corpus_diverse_v1/train.bin"; TRAIN_SHA = "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9"
16
+ SEG2 = 290810504 # début du segment multi_lang_v1 (manifest.segments) ; [290810502, 290810504) = séparateur b"\n\n"
17
+ WIN = { # nom : (chemin, sha256 attendu, clé du masque propre dans clean_masks/broad_gutenberg_v1_2134.npz)
18
+ "test20k_old": ("spira_m7/windows/test20k.bin", "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22", "m7_test20k"),
19
+ "fc2": ("broad/freshcode_v2.bin", "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3", "bench_fc2"),
20
+ "fresh_en": ("spira_m7/windows/fresh_en.bin", "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a", "bench_fresh_en"),
21
+ "fresh_fr": ("spira_m7/windows/fresh_fr.bin", "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715", "bench_fresh_fr"),
22
+ "test_v3": ("corpus_v3/test.bin", "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84", "bench_test_v3"),
23
+ "queries": ("spira_m7/windows/queries.bin", "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706", "bench_queries"),
24
+ "bg1_test": ("broad/broad_gutenberg_v1/test.bin", "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9", "broad_test_bin"),
25
+ }
26
+ MASKS = f"{S}/checker/scale/clean_masks/broad_gutenberg_v1_2134.npz"
27
+ WS = np.zeros(256, bool); WS[[9, 10, 11, 12, 32]] = True
28
+ LOW = np.arange(256, dtype=np.uint8); LOW[65:91] += 32
29
+ RSS_CAP_KB = 295 * 1024
30
+ def rss(): return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
31
+ def guard():
32
+ if rss() > RSS_CAP_KB: raise SystemExit(f"ABANDON : pic RSS {rss()} kB > {RSS_CAP_KB} kB")
33
+
34
+ def H(a):
35
+ """a : uint8 ; hash Horner des 64-grammes commençant en 0..len-64."""
36
+ n = len(a) - K + 1
37
+ if n <= 0: return np.zeros(0, np.uint64)
38
+ h = np.zeros(n, np.uint64)
39
+ with np.errstate(over="ignore"):
40
+ for k in range(K): h *= P; h += a[k:k + n]
41
+ return h
42
+
43
+ class Norm:
44
+ """normalisation en flux ; feed(bytes, offset) -> (octets normalisés uint8, offsets d'origine int64)."""
45
+ def __init__(self): self.prev_ws = False
46
+ def feed(self, a, off):
47
+ a = np.frombuffer(a, np.uint8) if not isinstance(a, np.ndarray) else a
48
+ kcr = a != 13; idx = np.flatnonzero(kcr); b = LOW[a[idx]]; ws = WS[b]; b[ws] = 32
49
+ if len(b) == 0: return b, idx.astype(np.int64)
50
+ pw = np.empty_like(ws); pw[0] = self.prev_ws; pw[1:] = ws[:-1]; keep = ~(ws & pw); self.prev_ws = bool(ws[-1])
51
+ return b[keep], idx[keep].astype(np.int64) + off
52
+
53
+ def form_bytes(raw, form):
54
+ a = np.frombuffer(raw, np.uint8)
55
+ if form == "raw": return a, None
56
+ b, m = Norm().feed(a, 0); return b, m.astype(np.int32)
57
+
58
+ def build_table(wins, form):
59
+ """wins : {nom: bytes}. Renvoie U (hash uniques triés), REP (offset global d'un représentant dans E), BITS (fenêtres), E, infos."""
60
+ names = list(wins); parts, maps, base, starts = [], {}, 0, {}
61
+ for nm in names:
62
+ b, m = form_bytes(wins.pop(nm), form); parts.append(b.copy() if form == "raw" else b); maps[nm] = m; starts[nm] = (base, len(b)); base += len(b)
63
+ E = np.concatenate(parts); del parts
64
+ # version économe (tient sous prlimit --as 300 Mio) : table pré-allouée, G et B déduits de l'indice de tri
65
+ cnt = np.array([max(starts[nm][1] - K + 1, 0) for nm in names], np.int64); cum = np.concatenate([[0], np.cumsum(cnt)])
66
+ Hc = np.empty(int(cum[-1]), np.uint64)
67
+ for i, nm in enumerate(names):
68
+ b0, L = starts[nm]; Hc[cum[i]:cum[i + 1]] = H(E[b0:b0 + L])
69
+ o = np.argsort(Hc, kind="stable").astype(np.int32); guard(); Hc = Hc[o]; guard()
70
+ first = np.ones(len(Hc), bool); first[1:] = Hc[1:] != Hc[:-1]; U = Hc[first]; del Hc
71
+ wbase = np.array([starts[nm][0] for nm in names], np.int64)
72
+ def gofs(ix): # indice dans Hc concaténé -> (offset global dans E, fenêtre)
73
+ w = np.searchsorted(cum, ix, "right") - 1; return (ix - cum[w] + wbase[w]), w
74
+ fidx = np.flatnonzero(first).astype(np.int32); REP = np.empty(len(fidx), np.int32); BITS = np.zeros(len(fidx), np.uint8)
75
+ W8 = np.empty(len(o), np.uint8)
76
+ for s in range(0, len(o), 1 << 20):
77
+ w = np.searchsorted(cum, o[s:s + (1 << 20)], "right") - 1; W8[s:s + (1 << 20)] = np.left_shift(1, w).astype(np.uint8); del w
78
+ for s in range(0, len(fidx), 1 << 20):
79
+ REP[s:s + (1 << 20)] = gofs(o[fidx[s:s + (1 << 20)]])[0].astype(np.int32)
80
+ BITS[:] = np.bitwise_or.reduceat(W8, fidx); del W8; guard()
81
+ # collisions internes : même hash, octets différents
82
+ first = ~first; dup = np.flatnonzero(first).astype(np.int32); del first; coll = 0; ar = np.arange(K)
83
+ for s in range(0, len(dup), 20000):
84
+ d = dup[s:s + 20000]; g = np.searchsorted(fidx, d, "right") - 1; gd = gofs(o[d])[0]
85
+ coll += int((E[gd[:, None] + ar] != E[REP[g].astype(np.int64)[:, None] + ar]).any(1).sum())
86
+ del o, dup, fidx; guard()
87
+ return U, REP, BITS, E, starts, maps, coll, names
88
+
89
+ def scan(src, U, REP, BITS, E, form, chunk, nwin):
90
+ """src : chemin ou bytes. Renvoie FOUND (bool sur U), hits (offsets train début/fin, bits), compteurs."""
91
+ FOUND = np.zeros(len(U), bool); hs, he, hb = [], [], []; cand = fp = npos = 0; sha = hashlib.sha256(); ar = np.arange(K)
92
+ nz = Norm(); tail = np.zeros(0, np.uint8); tidx = np.zeros(0, np.int64); pos = 0
93
+ f = open(src, "rb") if isinstance(src, str) else None; mv = memoryview(src) if f is None else None
94
+ while True:
95
+ blk = f.read(chunk) if f else bytes(mv[pos:pos + chunk])
96
+ if not blk: break
97
+ sha.update(blk); a = np.frombuffer(blk, np.uint8)
98
+ if form == "raw": nb, ni = a, None
99
+ else: nb, ni = nz.feed(a, pos)
100
+ buf = np.concatenate([tail, nb])
101
+ if form == "raw": cst = pos - len(tail)
102
+ else: bidx = np.concatenate([tidx, ni])
103
+ h = H(buf); npos += len(h)
104
+ if len(h):
105
+ i = np.searchsorted(U, h); i[i >= len(U)] = 0; hit = np.flatnonzero(U[i] == h)
106
+ if len(hit):
107
+ cand += len(hit); ui = i[hit]; ok = np.ones(len(hit), bool)
108
+ for s in range(0, len(hit), 20000):
109
+ j = hit[s:s + 20000]; r = REP[ui[s:s + 20000]]
110
+ ok[s:s + 20000] = (buf[j[:, None] + ar] == E[r.astype(np.int64)[:, None] + ar]).all(1)
111
+ fp += int((~ok).sum()); hit = hit[ok]; ui = ui[ok]; FOUND[ui] = True
112
+ if form == "raw": st = hit.astype(np.int64) + cst; en = st + K
113
+ else: st = bidx[hit]; en = bidx[hit + K - 1] + 1
114
+ hs.append(st); he.append(en); hb.append(BITS[ui])
115
+ pos += len(blk); keep = min(K - 1, len(buf)); tail = buf[len(buf) - keep:].copy()
116
+ if form != "raw": tidx = bidx[len(bidx) - keep:].copy()
117
+ del h, buf; guard()
118
+ if f: f.close()
119
+ cat = lambda L, dt: np.concatenate(L) if L else np.zeros(0, dt)
120
+ return FOUND, cat(hs, np.int64), cat(he, np.int64), cat(hb, np.uint8), cand, fp, npos, pos, sha.hexdigest()
121
+
122
+ def merge(st, en):
123
+ if len(st) == 0: return np.zeros((0, 2), np.int64)
124
+ o = np.argsort(st, kind="stable"); st, en = st[o], en[o]; em = np.maximum.accumulate(en)
125
+ new = np.ones(len(st), bool); new[1:] = st[1:] > em[:-1]; si = np.flatnonzero(new); ei = np.r_[si[1:], len(st)] - 1
126
+ return np.stack([st[si], em[ei]], 1)
127
+
128
+ def per_window(U, FOUND, E, starts, maps, names, nwin_bytes):
129
+ out, cov_all = {}, {}
130
+ for nm in names:
131
+ b0, L = starts[nm]; h = H(E[b0:b0 + L]); fw = np.zeros(len(h), bool)
132
+ for s0 in range(0, len(h), 1 << 19): fw[s0:s0 + (1 << 19)] = FOUND[np.searchsorted(U, h[s0:s0 + (1 << 19)])]
133
+ nh = int(len(h)); ndf = int(len(np.unique(h[fw]))); n0 = nwin_bytes[nm]; d = np.zeros(n0 + 1, np.int32); s = np.flatnonzero(fw)
134
+ if maps[nm] is None: a0, a1 = s, s + K
135
+ else: m = maps[nm]; a0, a1 = m[s].astype(np.int64), m[s + K - 1].astype(np.int64) + 1
136
+ np.add.at(d, a0, 1); np.add.at(d, a1, -1); np.cumsum(d, dtype=np.int32, out=d); cov = d[:n0] > 0; del d, h
137
+ c = np.zeros(n0 + 1, np.int32); np.cumsum(cov, dtype=np.int32, out=c[1:]); lo = np.zeros(n0, np.int32); lo[K:] = c[:n0 - K]
138
+ np.subtract(c[1:], lo, out=lo); excl = lo > 0; del c, lo
139
+ out[nm] = {"n64": nh, "n64_found": int(fw.sum()), "frac64_found": float(fw.mean()) if nh else 0.0,
140
+ "n64_distinct_found": ndf,
141
+ "eval_bytes": n0, "eval_bytes_covered": int(cov.sum()), "eval_bytes_excl_ctx64": int(excl.sum())}
142
+ cov_all[nm] = (cov, excl)
143
+ return out, cov_all
144
+
145
+ def run(form):
146
+ t0 = time.time(); wins = {}; wsha = {}
147
+ for nm, (rel, sh, _) in WIN.items():
148
+ d = open(f"{S}/{rel}", "rb").read(); s = hashlib.sha256(d).hexdigest(); assert s == sh, (nm, s); wins[nm] = d; wsha[nm] = s
149
+ nbytes = {k: len(v) for k, v in wins.items()}; U, REP, BITS, E, starts, maps, coll, names = build_table(wins, form); del wins
150
+ print(f"{form} table {len(U)} uniques, collisions internes {coll}, rss {rss()} kB, {time.time()-t0:.1f} s", flush=True)
151
+ FOUND, st, en, bits, cand, fp, npos, tb, tsha = scan(TRAIN, U, REP, BITS, E, form, 1 << 20, len(names))
152
+ print(f"{form} scan {tb} o, cand {cand}, fp {fp}, rss {rss()} kB, {time.time()-t0:.1f} s", flush=True)
153
+ del REP, BITS; guard(); pw, covs = per_window(U, FOUND, E, starts, maps, names, nbytes)
154
+ M = np.load(MASKS); tr = {}; rng_all = merge(st, en)
155
+ for i, nm in enumerate(names):
156
+ sel = (bits & np.uint8(1 << i)) > 0; s1, e1 = st[sel], en[sel]; R = merge(s1, e1)
157
+ cov, excl = covs[nm]; mk = WIN[nm][2]; mc, me = M[f"{mk}__covered"], M[f"{mk}__excl"]
158
+ pw[nm].update({"window_sha256": wsha[nm], "train_positions_matched": int(sel.sum()),
159
+ "train_positions_seg_bg1": int((s1 < SEG2).sum()), "train_positions_seg_multilang": int((s1 >= SEG2).sum()),
160
+ "train_ranges_merged": int(len(R)), "train_bytes_in_ranges": int((R[:, 1] - R[:, 0]).sum()) if len(R) else 0,
161
+ "train_range_offsets_sample": [[int(a), int(b)] for a, b in R[:3]] + ([[int(a), int(b)] for a, b in R[-2:]] if len(R) > 3 else []),
162
+ "xcheck_mask_2134": {"key": mk, "mask_covered": int(mc.sum()), "mask_excl": int(me.sum()),
163
+ "covered_identical_to_mask": bool(np.array_equal(cov, mc)), "covered_outside_mask_excl": int((cov & ~me).sum()),
164
+ "excl_identical_to_mask": bool(np.array_equal(excl, me))}})
165
+ tr[nm] = R
166
+ np.savez_compressed(f"{OD}/masks_{form}.npz", **{f"{nm}__covered": np.packbits(covs[nm][0]) for nm in names},
167
+ **{f"{nm}__excl_ctx64": np.packbits(covs[nm][1]) for nm in names}, **{f"{nm}__len": np.int64(nbytes[nm]) for nm in names})
168
+ np.savez_compressed(f"{OD}/train_ranges_{form}.npz", all=rng_all, **{nm: tr[nm] for nm in names})
169
+ sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
170
+ out = {"form": form, "k": K, "hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
171
+ "normalisation": None if form == "raw" else "suppr. \\r ; A-Z->a-z ASCII ; suites [ \\t\\n\\v\\f] -> 1 espace ; en flux",
172
+ "train": TRAIN, "train_bytes": tb, "train_sha256": tsha, "train_sha_ok": tsha == TRAIN_SHA, "train_64gram_positions_hashed": npos,
173
+ "table_unique_hashes": int(len(U)), "table_internal_collisions": coll, "candidates": cand, "hash_false_positives_rejected": fp,
174
+ "train_positions_matched_any": int(len(st)), "train_ranges_merged_any": int(len(rng_all)),
175
+ "train_bytes_in_ranges_any": int((rng_all[:, 1] - rng_all[:, 0]).sum()) if len(rng_all) else 0,
176
+ "train_positions_seg_multilang_any": int((st >= SEG2).sum()), "windows": pw,
177
+ "files": {f"masks_{form}.npz": sha(f"{OD}/masks_{form}.npz"), f"train_ranges_{form}.npz": sha(f"{OD}/train_ranges_{form}.npz")},
178
+ "elapsed_s": round(time.time() - t0, 1), "peak_rss_kB": rss(), "script_sha256": sha(os.path.abspath(__file__))}
179
+ json.dump(out, open(f"{OD}/dedup64_{form}.json", "w"), indent=1)
180
+ print(json.dumps({k: v["n64_found"] for k, v in pw.items()}), out["elapsed_s"], "s", out["peak_rss_kB"], "kB", flush=True)
181
+
182
+ def selftest():
183
+ rng = np.random.default_rng(7); res = {}; ok_all = True
184
+ def rb(n): return bytes(rng.integers(0, 256, n, dtype=np.uint8))
185
+ def tx(n): return bytes(rng.choice(np.frombuffer(b"abcdefghij KLMNOP\n\r\t.,", np.uint8), n))
186
+ # T1 hash : Horner vectoriel == boucle Python
187
+ a = np.frombuffer(rb(300), np.uint8); h = H(a); M64 = (1 << 64) - 1
188
+ def hp(x):
189
+ v = 0
190
+ for c in x: v = (v * 0x9E3779B97F4A7C15 + int(c)) & M64
191
+ return v
192
+ res["T1_hash_vs_python"] = all(int(h[i]) == hp(a[i:i + K]) for i in (0, 1, 100, 236));
193
+ # T2 normalisation en flux == normalisation globale, plusieurs tailles de bloc (frontières au milieu de suites d'espaces / \r\n)
194
+ t = tx(5000) + b" \r\n\r\n X" + tx(3000); ref, refi = Norm().feed(np.frombuffer(t, np.uint8), 0)
195
+ py = bytes(t).replace(b"\r", b"").lower(); import re; py = re.sub(rb"[ \t\n\x0b\x0c]+", b" ", py)
196
+ t2 = True
197
+ for cs in (1, 7, 63, 64, 100, 4096):
198
+ nz = Norm(); parts, idxs = [], []
199
+ for s in range(0, len(t), cs): b, i = nz.feed(np.frombuffer(t[s:s + cs], np.uint8), s); parts.append(b); idxs.append(i)
200
+ t2 &= np.array_equal(np.concatenate(parts), ref) and np.array_equal(np.concatenate(idxs), refi)
201
+ res["T2_norm_stream_eq_global_eq_regex"] = bool(t2 and ref.tobytes() == py)
202
+ # T3/T4 : doublons plantés à cheval sur une frontière de bloc (raw exact ; norm : casse/espaces/\r modifiés)
203
+ ev = {"w0": tx(2000), "w1": tx(1500)}; CH = 1000
204
+ g_raw = ev["w0"][300:300 + K]
205
+ g_n = ev["w1"][500:500 + 80]; gnorm = Norm().feed(np.frombuffer(g_n, np.uint8), 0)[0].tobytes()
206
+ variant = gnorm.upper().replace(b" ", b" \r\n\t ") # même forme normalisée, octets bruts différents
207
+ train = bytearray(tx(10000))
208
+ train = train.replace(g_raw, b"").replace(g_raw[:32], b"") # pas d'occurrence fortuite
209
+ p1 = 3 * CH - 30; train[p1:p1 + K] = g_raw # raw à cheval sur 3000
210
+ p2 = 6 * CH - 40; train[p2:p2 + len(variant)] = variant # variante à cheval sur 6000
211
+ p3 = 8 * CH - 10; train[p3:p3 + 63] = g_raw[:63] # quasi-doublon 63 o : ne doit PAS compter en raw
212
+ train = bytes(train)
213
+ for form in ("raw", "norm"):
214
+ U, REP, BITS, E, starts, maps, coll, names = build_table(dict(ev), form)
215
+ FOUND, st, en, bits, cand, fp, npos, tb, tsha = scan(train, U, REP, BITS, E, form, CH, len(names))
216
+ # brute force : ensemble Python de tous les 64-grammes de la forme
217
+ def grams(x): return {x[i:i + K] for i in range(len(x) - K + 1)}
218
+ fx = (lambda x: x) if form == "raw" else (lambda x: Norm().feed(np.frombuffer(x, np.uint8), 0)[0].tobytes())
219
+ eg = grams(fx(ev["w0"])) | grams(fx(ev["w1"])); tn = fx(train); bf = sum(1 for i in range(len(tn) - K + 1) if tn[i:i + K] in eg)
220
+ nfull = 0
221
+ for c in (1 << 20,):
222
+ F2 = scan(train, U, REP, BITS, E, form, c, len(names)); nfull = len(F2[1])
223
+ r = {"hits": int(len(st)), "bruteforce": bf, "one_chunk_hits": nfull, "starts": sorted(set(int(x) for x in st))[:5], "fp": fp, "coll": coll, "tsha_ok": tsha == hashlib.sha256(train).hexdigest()}
224
+ if form == "raw": r["planted_raw_found_at_p1"] = p1 in set(st.tolist()); r["near_miss_63_not_found"] = p3 not in set(st.tolist())
225
+ else: r["planted_variant_found_in_p2_range"] = bool(((st >= p2) & (st < p2 + len(variant))).any()); r["info_raw64_plant_seen_in_norm"] = bool(((st >= p1 - 5) & (st <= p1 + 5)).any())
226
+ r["pass"] = (r["hits"] == bf == nfull and r["tsha_ok"] and fp == 0 and all(v for k, v in r.items() if k.startswith("planted") or k.startswith("near")))
227
+ if form == "raw": r["pass"] &= r["hits"] >= 1
228
+ res[f"T3_{form}_chunk_boundary"] = r
229
+ ok_all = res["T1_hash_vs_python"] and res["T2_norm_stream_eq_global_eq_regex"] and res["T3_raw_chunk_boundary"]["pass"] and res["T3_norm_chunk_boundary"]["pass"]
230
+ res["ALL_PASS"] = bool(ok_all); res["peak_rss_kB"] = rss()
231
+ json.dump(res, open(f"{OD}/selftest.json", "w"), indent=1); print(json.dumps(res), flush=True)
232
+
233
+ if __name__ == "__main__":
234
+ selftest() if sys.argv[1] == "selftest" else run(sys.argv[1])
v3_scale/checker/recount/corpus_diverse_v1_dedup/run.sh ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Checker — lance une forme : prlimit --as 2 Gio (filet), nice 19, OMP 1 ; CHIEN DE GARDE RSS : sonde VmRSS toutes les 1 s,
3
+ # tue UNIQUEMENT son propre processus python si VmRSS > 300 Mo (307200 kB). Pic VmHWM noté dans run_<form>.mem.
4
+ export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 MALLOC_MMAP_THRESHOLD_=65536 MALLOC_TRIM_THRESHOLD_=0
5
+ cd "$(dirname "$0")"; F=$1; CAP=307200
6
+ echo "$(date '+%F %T %Z') START $F" > run_$F.mem
7
+ prlimit --as=2147483648 nice -n 19 /workspace/SPIRA-venv/bin/python -u dedup64_div1.py $F > run_$F.log 2>&1 & P=$!
8
+ pk=0; killed=0
9
+ while kill -0 $P 2>/dev/null; do
10
+ r=$(awk '/VmRSS/{print $2}' /proc/$P/status 2>/dev/null); h=$(awk '/VmHWM/{print $2}' /proc/$P/status 2>/dev/null)
11
+ [ -n "$h" ] && [ "$h" -gt "$pk" ] && pk=$h
12
+ if [ -n "$r" ] && [ "$r" -gt $CAP ]; then kill $P; killed=1; echo "$(date '+%T') WATCHDOG kill own pid $P VmRSS=$r kB" >> run_$F.mem; fi
13
+ sleep 1
14
+ done
15
+ wait $P; rc=$?; echo "$(date '+%F %T %Z') END $F rc=$rc killed=$killed VmHWM_polled_kB=$pk" >> run_$F.mem