Skip to content

Commit

Permalink
Add CERT from George Woltman
Browse files Browse the repository at this point in the history
  • Loading branch information
preda committed Oct 25, 2024
1 parent 60930a0 commit 73b96eb
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 3 deletions.
68 changes: 67 additions & 1 deletion src/Gpu.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright Mihai Preda and George Woltman.
// Copyright (C) Mihai Preda and George Woltman.

#include "Gpu.h"
#include "Proof.h"
Expand All @@ -15,6 +15,7 @@
#include "timeutil.h"
#include "TrigBufCache.h"
#include "fs.h"
#include "Sha3Hash.h"

#include <algorithm>
#include <bitset>
Expand Down Expand Up @@ -1616,6 +1617,71 @@ LLResult Gpu::isPrimeLL(const Task& task) {
}
}

array<u64, 4> Gpu::isCERT(const Task& task) {
assert(E == task.exponent);
wantROE = 0;

// Get CERT start value
char fname[32];
sprintf(fname, "M%u.cert", E);
File fi = File::openReadThrow(fname);

//We need to gracefully handle the CERT file missing. There is a window in primenet.py between worktodo.txt entry and starting value download.

u32 nBytes = (E - 1) / 8 + 1;
Words B = fi.readBytesLE(nBytes);

writeIn(bufData, std::move(B));

Timer elapsedTimer;

elapsedTimer.reset();

u32 startK = 0;

IterationTimer iterationTimer{startK};

u32 k = 0;
u32 kEnd = task.squarings;
bool leadIn = true;

while (true) {
++k;
bool doStop = (k >= kEnd);

if (Signal::stopRequested()) {
doStop = true;
log("Stopping, please wait..\n");
}

bool doLog = (k % 100'000 == 0) || doStop;
bool leadOut = doLog || useLongCarry;

squareCERT(bufData, leadIn, leadOut);
leadIn = leadOut;

if (!doLog) {
if (k % args.flushStep == 0) { queue->finish(); } // Periodically flush the queue
continue;
}

Words data = readData();
assert(data.size() >= 2);
u64 res64 = (u64(data[1]) << 32) | data[0];

float secsPerIt = iterationTimer.reset(k);
log("%9u %016" PRIx64 " %4.0f\n", k, res64, secsPerIt * 1'000'000);

if (k >= kEnd) {
fs::remove (fname);
return std::move(SHA3{}.update(data.data(), (E-1)/8+1)).finish();
}

if (doStop) { throw "stop requested"; }
}
}


void Gpu::clear(bool isPRP) {
if (isPRP) {
Saver<PRPState>::clear(E);
Expand Down
3 changes: 3 additions & 0 deletions src/Gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class Gpu {
void writeIn(Buffer<int>& buf, vector<i32>&& words);

void square(Buffer<int>& out, Buffer<int>& in, bool leadIn, bool leadOut, bool doMul3 = false, bool doLL = false);
void squareCERT(Buffer<int>& io, bool leadIn, bool leadOut) { square(io, io, leadIn, leadOut, false, false); }
void squareLL(Buffer<int>& io, bool leadIn, bool leadOut) { square(io, io, leadIn, leadOut, false, true); }

void square(Buffer<int>& io);
Expand Down Expand Up @@ -252,6 +253,8 @@ class Gpu {

PRPResult isPrimePRP(const Task& task);
LLResult isPrimeLL(const Task& task);
array<u64, 4> isCERT(const Task& task);

double timePRP();

tuple<bool, u64, RoeInfo, RoeInfo> measureROE(bool quick);
Expand Down
20 changes: 20 additions & 0 deletions src/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ void Task::writeResultLL(const Args &args, bool isPrime, u64 res64, u32 fftSize)
writeResult(exponent, "LL", isPrime ? "P" : "C", AID, args, fields);
}

void Task::writeResultCERT(const Args &args, array <u64, 4> hash, u32 squarings, u32 fftSize) const {
string hexhash = hex(hash[3]) + hex(hash[2]) + hex(hash[1]) + hex(hash[0]);
vector<string> fields{json("worktype", "Cert"),
json("exponent", exponent),
json("sha3-hash", hexhash.c_str()),
json("squarings", squarings),
json("fft-length", fftSize),
json("shift-count", 0),
json("error-code", "00000000"), // I don't know the meaning of this
};
fields += tailFields(AID, args);
string s = json(std::move(fields));
log("%s\n", s.c_str());
File::append(args.resultsFile, s + '\n');
}

void Task::execute(GpuCommon shared, Queue *q, u32 instance) {
if (kind == VERIFY) { exponent = proof::getInfo(verifyPath).exp; }

Expand Down Expand Up @@ -214,6 +230,10 @@ void Task::execute(GpuCommon shared, Queue *q, u32 instance) {
} else {
gpu->clear(kind == PRP);
}
} else if (kind == CERT) {
auto sha256 = gpu->isCERT(*this);
writeResultCERT(*shared.args, sha256, squarings, fft.size());
Worktodo::deleteTask(*this, instance);
} else {
throw "Unexpected task kind " + to_string(kind);
}
Expand Down
4 changes: 3 additions & 1 deletion src/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ class TrigBufCache;

class Task {
public:
enum Kind {PRP, VERIFY, LL};
enum Kind {PRP, VERIFY, LL, CERT};

Kind kind;
u32 exponent;
string AID; // Assignment ID
string line; // the verbatim worktodo line, used in deleteTask().
u32 squarings; // For CERTs

string verifyPath; // For Verify
void execute(GpuCommon shared, Queue* q, u32 instance);

void writeResultPRP(const Args&, bool isPrime, u64 res64, const std::string& res2048, u32 fftSize, u32 nErrors, const fs::path& proofPath) const;
void writeResultLL(const Args&, bool isPrime, u64 res64, u32 fftSize) const;
void writeResultCERT(const Args&, array <u64, 4> hash, u32 squarings, u32 fftSize) const;
};
27 changes: 26 additions & 1 deletion src/Worktodo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,24 @@ bool isHex(const string& s) {
// Examples:
// PRP=FEEE9DCD59A0855711265C1165C4C693,1,2,124647911,-1,77,0
// DoubleCheck=E0F583710728343C61643028FBDBA0FB,70198703,75,1
// Cert=B2EE67DC0A514753E488794C9DD6F6BD,1,2,82997591,-1,162105
std::optional<Task> parse(const std::string& line) {
if (line.empty() || line[0] == '#') { return {}; }

vector<string> topParts = split(line, '=');

bool isPRP = false;
bool isLL = false;
bool isCERT = false;

if (topParts.size() == 2) {
string kind = topParts.front();
if (kind == "PRP" || kind == "PRPDC") {
isPRP = true;
} else if (kind == "Test" || kind == "DoubleCheck") {
isLL = true;
} else if (kind == "Cert") {
isCERT = true;
}
}

Expand All @@ -61,7 +65,28 @@ std::optional<Task> parse(const std::string& line) {
u64 exp{};
auto [ptr, _] = from_chars(s.c_str(), end, exp, 10);
if (ptr != end) { exp = 0; }
if (exp > 1000) { return {{isPRP ? Task::PRP : Task::LL, u32(exp), AID, line}}; }
if (exp > 1000) { return {{isPRP ? Task::PRP : Task::LL, u32(exp), AID, line, 0}}; }
}
if (isCERT) {
vector<string> parts = split(topParts.back(), ',');
if (!parts.empty() && parts.front().size() == 32 && isHex(parts.front())) {
string AID;
AID = parts.front();
parts.erase(parts.begin());

if (parts.size() == 5 && parts[0] == "1" && parts[1] == "2" && parts[3] == "-1") {
string s = parts[2];
const char *end = s.c_str() + s.size();
u64 exp{0};
from_chars(s.c_str(), end, exp, 10);
s = parts[4];
end = s.c_str() + s.size();
u64 squarings{0};
from_chars(s.c_str(), end, squarings, 10);
//printf ("Exec cert %d %d \n", (int) exp, (int) squarings);
if (exp > 1000 && squarings > 100) { return {{Task::CERT, u32(exp), AID, line, u32(squarings) }}; }
}
}
}
log("worktodo.txt line ignored: \"%s\"\n", rstripNewline(line).c_str());
return {};
Expand Down

0 comments on commit 73b96eb

Please sign in to comment.