Skip to content

Commit bbb38a2

Browse files
Better known factor / not known handling in json
1 parent 1742a89 commit bbb38a2

File tree

7 files changed

+698
-32
lines changed

7 files changed

+698
-32
lines changed

chainpm1old.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
14
# chainpm1old.sh
25
# Extend P-1 stage 1 from existing .save/.p95 at <old_B1>: <RESUME_FLAG> <old_B1> -b1 <old_B1+step>.
36
# Stop if "P-1 factor stage 1 found:" appears.
47
# Usage: ./chainpm1old.sh <exp> <old_B1> <step>
58

6-
#!/usr/bin/env bash
7-
set -euo pipefail
8-
99
if [ $# -ne 3 ]; then
1010
echo "Usage: $0 <exponent> <old_B1> <step>" >&2
1111
exit 1
@@ -22,13 +22,19 @@ while :; do
2222
next=$(( curr + step ))
2323
log="pm1_p${p}_B1_${curr}_to_${next}.log"
2424
echo "[INFO] Run: ${PROG} ${p} -pm1 ${RESUME_FLAG} ${curr} -b1 ${next}"
25+
2526
set +e
2627
"${PROG}" "${p}" -pm1 "${RESUME_FLAG}" "${curr}" -b1 "${next}" | tee "${log}"
2728
set -e
29+
2830
if grep -q "P-1 factor stage 1 found:" "${log}"; then
2931
factor=$(sed -n 's/.*P-1 factor stage 1 found: \([0-9][0-9]*\).*/\1/p' "${log}" | head -n1)
3032
echo "[FOUND] Factor ${factor} between B1=${curr} and B1=${next}"
31-
exit 0
33+
# On continue, pas d'exit ici
3234
fi
35+
36+
# Supprimer les checkpoints courants avant le prochain run
37+
rm -f ./*.ck*
38+
3339
curr=${next}
3440
done

include/core/App.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class App {
4949
int runPM1Marin();
5050
int runPM1Stage2();
5151
int runPM1Stage2Marin();
52+
int runPM1Stage3Marin();
5253
int runPM1Stage2MarinNKVersion();
5354
int runMemtestOpenCL();
5455
int runECMMarin();

include/io/CliParser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct CliOptions {
8787
int res64_display_interval = 0;
8888
bool cl_queue_throttle_active = false;
8989
std::vector<std::string> knownFactors;
90+
std::vector<std::string> knownFactors_start;
9091
bool gui = false;
9192
int http_port = 3131;
9293
std::string http_host = "localhost";
@@ -95,6 +96,7 @@ struct CliOptions {
9596
uint64_t curves_tested_for_found = 0;
9697
int invarianterror = 0;
9798
uint32_t ecm_progress_interval_ms = 2000;
99+
bool s3only = false;
98100
};
99101

100102
class CliParser {

src/core/App.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ App::App(int argc, char** argv)
279279
: (e->pm1Test ? "pm1" : "")));
280280
o.aid = e->aid;
281281
o.knownFactors = e->knownFactors;
282+
o.knownFactors_start.assign(e->knownFactors.begin(), e->knownFactors.end());
283+
282284

283285
if (e->pm1Test) {
284286
o.B1 = e->B1;
@@ -836,8 +838,17 @@ int App::run() {
836838

837839
bool haveS1 = File(s1f).exists() || File(s1f + ".old").exists();
838840
bool haveS2 = File(s2f).exists() || File(s2f + ".old").exists() || File(s2f + ".new").exists();
841+
if(options.s3only){
842+
std::ostringstream msg;
843+
msg << "S3 only requested "
844+
<< "→ jumping to runPM1Stage3Marin()";
845+
std::cout << msg.str() << std::endl;
846+
if (guiServer_) { guiServer_->appendLog(msg.str()); guiServer_->setStatus("Stage 3 only"); }
839847

840-
if ((haveS2) && options.nmax == 0 && options.K == 0) {
848+
rc_local = runPM1Stage3Marin();
849+
ran_local = true;
850+
}
851+
else if ((haveS2) && options.nmax == 0 && options.K == 0) {
841852
std::ostringstream msg;
842853
msg << "Detected P-1 checkpoint(s): "
843854
<< (haveS2 ? "[Stage 2] " : "")

src/io/CliParser.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ CliOptions CliParser::parse(int argc, char** argv ) {
203203
else if (std::strcmp(argv[i], "-marin") == 0) {
204204
opts.marin = false;
205205
}
206+
else if (std::strcmp(argv[i], "-s3") == 0) {
207+
opts.s3only = true;
208+
}
206209
else if (std::strcmp(argv[i], "-montgomery") == 0) {
207210
opts.edwards = false;
208211
}
@@ -306,6 +309,10 @@ CliOptions CliParser::parse(int argc, char** argv ) {
306309
opts.B3 = std::strtoull(argv[i + 1], nullptr, 10); // base 10
307310
++i;
308311
}
312+
else if (std::strcmp(argv[i], "-b4") == 0 && i + 1 < argc) {
313+
opts.B4 = std::strtoull(argv[i + 1], nullptr, 10); // base 10
314+
++i;
315+
}
309316
else if (std::strcmp(argv[i], "-K") == 0 && i + 1 < argc) {
310317
opts.K = std::strtoull(argv[i + 1], nullptr, 10); // base 10
311318
++i;
@@ -421,6 +428,8 @@ CliOptions CliParser::parse(int argc, char** argv ) {
421428
}
422429
else if (strcmp(argv[i], "-factors") == 0 && i + 1 < argc) {
423430
opts.knownFactors = util::split(argv[++i], ',');
431+
//opts.knownFactors_start = util::split(argv[++i], ',');
432+
opts.knownFactors_start.assign(opts.knownFactors.begin(), opts.knownFactors.end());
424433
}
425434

426435
else if (argv[i][0] != '-') {

src/io/JsonBuilder.cpp

Lines changed: 141 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <cctype>
3030
#include <regex>
3131
#include <string>
32+
#include <unordered_set>
3233

3334
namespace io{
3435

@@ -72,6 +73,83 @@ static std::string toUpper(const std::string& s){
7273
return t;
7374
}
7475

76+
static std::vector<std::string> splitAndUniqFactorsBySelfDivision(
77+
const std::vector<std::string>& inFactors
78+
) {
79+
std::vector<mpz_class> f;
80+
f.reserve(inFactors.size());
81+
for (const auto& s : inFactors) {
82+
if (s.empty()) continue;
83+
mpz_class x;
84+
if (x.set_str(s, 10) != 0) continue;
85+
if (x < 0) x = -x;
86+
if (x > 1) f.push_back(x);
87+
}
88+
89+
auto normalize = [&](){
90+
f.erase(std::remove_if(f.begin(), f.end(),
91+
[](const mpz_class& v){ return v <= 1; }),
92+
f.end());
93+
std::sort(f.begin(), f.end());
94+
};
95+
96+
normalize();
97+
98+
bool changed = true;
99+
while (changed) {
100+
changed = false;
101+
normalize();
102+
103+
for (size_t i = 0; i < f.size() && !changed; ++i) {
104+
for (size_t j = 0; j < f.size(); ++j) {
105+
if (i == j) continue;
106+
if (f[j] <= 1) continue;
107+
108+
if (f[i] > f[j]) {
109+
if (mpz_divisible_p(f[i].get_mpz_t(), f[j].get_mpz_t())) {
110+
mpz_class q;
111+
mpz_tdiv_q(q.get_mpz_t(), f[i].get_mpz_t(), f[j].get_mpz_t());
112+
f[i] = f[j];
113+
if (q > 1) f.push_back(q);
114+
115+
changed = true;
116+
break;
117+
}
118+
}
119+
}
120+
}
121+
if (changed) continue;
122+
123+
for (size_t i = 0; i < f.size() && !changed; ++i) {
124+
for (size_t j = i + 1; j < f.size() && !changed; ++j) {
125+
mpz_class g;
126+
mpz_gcd(g.get_mpz_t(), f[i].get_mpz_t(), f[j].get_mpz_t());
127+
128+
if (g > 1 && g < f[i] && g < f[j]) {
129+
mpz_class ai, bj;
130+
mpz_tdiv_q(ai.get_mpz_t(), f[i].get_mpz_t(), g.get_mpz_t());
131+
mpz_tdiv_q(bj.get_mpz_t(), f[j].get_mpz_t(), g.get_mpz_t());
132+
133+
f[i] = g;
134+
f[j] = bj;
135+
if (ai > 1) f.push_back(ai);
136+
137+
changed = true;
138+
}
139+
}
140+
}
141+
}
142+
143+
normalize();
144+
f.erase(std::unique(f.begin(), f.end()), f.end());
145+
146+
std::vector<std::string> out;
147+
out.reserve(f.size());
148+
for (const auto& x : f) out.push_back(x.get_str(10));
149+
return out;
150+
}
151+
152+
75153
std::tuple<bool, std::string, std::string> JsonBuilder::computeResult(
76154
const std::vector<uint64_t>& hostResult,
77155
const CliOptions& opts,
@@ -259,7 +337,8 @@ static std::string generatePrimeNetJson(
259337
const std::string &aid,
260338
const std::string &timestamp,
261339
const std::string &computer,
262-
const std::vector<std::string>& knownFactors)
340+
const std::vector<std::string>& knownFactors,
341+
const std::vector<std::string>& knownFactors_start)
263342
{
264343
std::string canonWT;
265344
if (worktype == "prp") canonWT = "PRP-3";
@@ -269,25 +348,52 @@ static std::string generatePrimeNetJson(
269348
int torsion = opts.notorsion ? 0 : (opts.torsion16 ? 16 : 8);
270349
std::ostringstream oss;
271350

272-
std::vector<std::string> uniqFactors;
273-
uniqFactors.reserve(knownFactors.size());
274-
for (const auto& f : knownFactors) {
275-
if (std::find(uniqFactors.begin(), uniqFactors.end(), f) == uniqFactors.end()) {
276-
uniqFactors.push_back(f);
351+
352+
std::vector<std::string> startFactors =
353+
splitAndUniqFactorsBySelfDivision(knownFactors_start);
354+
355+
std::vector<std::string> allFactors = knownFactors;
356+
allFactors.insert(allFactors.end(), startFactors.begin(), startFactors.end());
357+
358+
std::vector<std::string> allSplit =
359+
splitAndUniqFactorsBySelfDivision(allFactors);
360+
361+
std::unordered_set<std::string> startSet(startFactors.begin(), startFactors.end());
362+
363+
std::vector<std::string> newFactors;
364+
newFactors.reserve(allSplit.size());
365+
for (const auto& f : allSplit) {
366+
if (!startSet.count(f)) newFactors.push_back(f);
367+
}
368+
369+
std::string factorStr;
370+
std::string factorStrQuoted;
371+
372+
if (!newFactors.empty()) {
373+
factorStr = newFactors[0];
374+
factorStrQuoted = "\"" + newFactors[0];
375+
for (size_t i = 1; i < newFactors.size(); ++i) {
376+
factorStr += "," + newFactors[i];
377+
factorStrQuoted += "\",\"" + newFactors[i];
277378
}
379+
factorStrQuoted += "\"";
278380
}
279381

280-
std::string knownFactorStr; // e.g. 204453287,1255070097822910516312001 -- for use in checksum
281-
std::string knownFactorStrQuoted; // e.g. "204453287","1255070097822910516312001" -- for use in JSON, note is already quoted and MUST NOT be wrapped in jsonEscape()
282-
if (!uniqFactors.empty()) {
283-
knownFactorStr = uniqFactors[0];
284-
knownFactorStrQuoted = "\"" + uniqFactors[0];
285-
for (size_t i = 1; i < uniqFactors.size(); ++i) {
286-
knownFactorStr += "," + uniqFactors[i];
287-
knownFactorStrQuoted += "\",\"" + uniqFactors[i];
382+
std::string startFactorStr;
383+
std::string startFactorStrQuoted;
384+
if (!startFactors.empty()) {
385+
startFactorStr = startFactors[0];
386+
startFactorStrQuoted = "\"" + startFactors[0];
387+
for (size_t i = 1; i < startFactors.size(); ++i) {
388+
startFactorStr += "," + startFactors[i];
389+
startFactorStrQuoted += "\",\"" + startFactors[i];
288390
}
289-
knownFactorStrQuoted += "\"";
391+
startFactorStrQuoted += "\"";
290392
}
393+
std::cerr << "[DBG] knownFactors_start=" << knownFactors_start.size()
394+
<< " knownFactors=" << knownFactors.size()
395+
<< " startFactors=" << startFactors.size()
396+
<< " newFactors=" << newFactors.size() << "\n";
291397

292398
oss << "{";
293399
oss << "\"status\":" << jsonEscape(status);
@@ -296,9 +402,17 @@ static std::string generatePrimeNetJson(
296402
if (!knownFactors.empty()) {
297403
// *** TODO: this is totally wrong, "known-factors" and "factors" are two ENTIRELY separate things, and should be better stored in the PrMers data structure
298404
if ((worktype == "ll") || (worktype == "llsafe") || (worktype == "prp")) {
299-
oss << ",\"known-factors\":[" << knownFactorStrQuoted << "]";
405+
oss << ",\"known-factors\":[" << startFactorStrQuoted << "]";
300406
} else {
301-
oss << ",\"factors\":[" << knownFactorStrQuoted << "]";
407+
if (!newFactors.empty()) {
408+
oss << ",\"factors\":[" << factorStrQuoted << "]";
409+
}
410+
411+
// Facteurs connus avant le run (worktodo)
412+
if (!startFactors.empty()) {
413+
oss << ",\"known-factors\":[" << startFactorStrQuoted << "]";
414+
}
415+
302416
}
303417
}
304418
if (opts.B1 > 0) {
@@ -365,15 +479,18 @@ static std::string generatePrimeNetJson(
365479
std::string canonWTNorm = canonWT;
366480
if (canonWTNorm == "PRP-3" || canonWTNorm == "prp-3") canonWTNorm = "PRP";
367481
canon << canonWTNorm << ";"; // worktype
368-
if (!(canonWTNorm == "PRP") && !knownFactors.empty()) {
482+
/*if (!(canonWTNorm == "PRP") && !knownFactors.empty()) {
369483
canon << knownFactorStr; // factors
370484
}
371485
canon << ";";
372486
if ((canonWTNorm == "PRP") && !knownFactors.empty()) {
373487
canon << knownFactorStr; // factors
374-
}
375-
376-
canon << "" << ";"; // known-factors *** TODO: not yet supported (factors that were known BEFORE this factoring run and included in worktodo.txt, distinct from factors just found ***
488+
}*/
489+
canon << factorStr;
490+
canon << ";";
491+
canon << startFactorStr;
492+
canon << ";";
493+
// known-factors *** TODO: not yet supported (factors that were known BEFORE this factoring run and included in worktodo.txt, distinct from factors just found ***
377494

378495
if (canonWT == "TF") {
379496
// *** TODO: not yet not yet implemented ***
@@ -441,7 +558,7 @@ static std::string generatePrimeNetJson(
441558
oss.str(""); oss.clear();
442559
oss << prefix
443560
<< ",\"checksum\":{\"version\":1,\"checksum\":\"" << hexss.str() << "\"}"
444-
//<< ",\"hash\":\"" << canon.str() << "\""
561+
<< ",\"hash\":\"" << canon.str() << "\""
445562
//<< ",\"code-hash\":" << jsonEscape(util::code_hash_crc32_upper8())
446563
<< "}";
447564
return oss.str();
@@ -494,7 +611,8 @@ std::string JsonBuilder::generate(const CliOptions& opts,
494611
opts.aid,
495612
timestampBuf,
496613
opts.computer_name,
497-
opts.knownFactors
614+
opts.knownFactors,
615+
opts.knownFactors_start
498616
);
499617
}
500618

0 commit comments

Comments
 (0)