|
@ -6,6 +6,7 @@ |
|
|
#include <stdlib.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <gmp.h>
|
|
|
#include <gmp.h>
|
|
|
#include <assert.h>
|
|
|
#include <assert.h>
|
|
|
|
|
|
#include <thread>
|
|
|
#include "calcwit.h"
|
|
|
#include "calcwit.h"
|
|
|
#include "utils.h"
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
@ -17,6 +18,8 @@ Circom_CalcWit::Circom_CalcWit(Circom_Circuit *aCircuit) { |
|
|
signalAssigned[0] = true; |
|
|
signalAssigned[0] = true; |
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
mutexes = new std::mutex[NMUTEXES]; |
|
|
|
|
|
cvs = new std::condition_variable[NMUTEXES]; |
|
|
inputSignalsToTrigger = new int[circuit->NComponents]; |
|
|
inputSignalsToTrigger = new int[circuit->NComponents]; |
|
|
signalValues = new BigInt[circuit->NSignals]; |
|
|
signalValues = new BigInt[circuit->NSignals]; |
|
|
|
|
|
|
|
@ -34,18 +37,6 @@ Circom_CalcWit::Circom_CalcWit(Circom_Circuit *aCircuit) { |
|
|
reset(); |
|
|
reset(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Circom_CalcWit::reset() { |
|
|
|
|
|
|
|
|
|
|
|
#ifdef SANITY_CHECK
|
|
|
|
|
|
for (int i=1; i<circuit->NComponents; i++) signalAssigned[i] = false; |
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<circuit->NComponents; i++) { |
|
|
|
|
|
inputSignalsToTrigger[i] = circuit->components[i].inputSignals; |
|
|
|
|
|
if (inputSignalsToTrigger[i] == 0) triggerComponent(i); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Circom_CalcWit::~Circom_CalcWit() { |
|
|
Circom_CalcWit::~Circom_CalcWit() { |
|
|
delete field; |
|
|
delete field; |
|
@ -54,13 +45,40 @@ Circom_CalcWit::~Circom_CalcWit() { |
|
|
delete signalAssigned; |
|
|
delete signalAssigned; |
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
delete[] cvs; |
|
|
|
|
|
delete[] mutexes; |
|
|
|
|
|
|
|
|
for (int i=0; i<circuit->NSignals; i++) mpz_clear(signalValues[i]); |
|
|
for (int i=0; i<circuit->NSignals; i++) mpz_clear(signalValues[i]); |
|
|
|
|
|
|
|
|
delete[] signalValues; |
|
|
delete[] signalValues; |
|
|
delete inputSignalsToTrigger; |
|
|
|
|
|
|
|
|
delete[] inputSignalsToTrigger; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Circom_CalcWit::syncPrintf(const char *format, ...) { |
|
|
|
|
|
va_list args; |
|
|
|
|
|
va_start(args, format); |
|
|
|
|
|
|
|
|
|
|
|
printf_mutex.lock(); |
|
|
|
|
|
vprintf(format, args); |
|
|
|
|
|
printf_mutex.unlock(); |
|
|
|
|
|
|
|
|
|
|
|
va_end(args); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Circom_CalcWit::reset() { |
|
|
|
|
|
|
|
|
|
|
|
#ifdef SANITY_CHECK
|
|
|
|
|
|
for (int i=1; i<circuit->NComponents; i++) signalAssigned[i] = false; |
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<circuit->NComponents; i++) { |
|
|
|
|
|
inputSignalsToTrigger[i] = circuit->components[i].inputSignals; |
|
|
|
|
|
if (inputSignalsToTrigger[i] == 0) triggerComponent(i); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Circom_CalcWit::getSubComponentOffset(int cIdx, u64 hash) { |
|
|
int Circom_CalcWit::getSubComponentOffset(int cIdx, u64 hash) { |
|
|
int hIdx; |
|
|
int hIdx; |
|
|
for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) { |
|
|
for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) { |
|
@ -121,7 +139,16 @@ void Circom_CalcWit::freeBigInts(PBigInt bi, int n) { |
|
|
delete[] bi; |
|
|
delete[] bi; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Circom_CalcWit::getSignal(int cIdx, int sIdx, PBigInt value) { |
|
|
|
|
|
|
|
|
void Circom_CalcWit::getSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value) { |
|
|
|
|
|
// syncPrintf("getSignal: %d\n", sIdx);
|
|
|
|
|
|
if (currentComponentIdx != cIdx) { |
|
|
|
|
|
std::unique_lock<std::mutex> lk(mutexes[cIdx % NMUTEXES]); |
|
|
|
|
|
while (inputSignalsToTrigger[cIdx] != -1) { |
|
|
|
|
|
cvs[cIdx % NMUTEXES].wait(lk); |
|
|
|
|
|
} |
|
|
|
|
|
// cvs[cIdx % NMUTEXES].wait(lk, [&]{return inputSignalsToTrigger[cIdx] == -1;});
|
|
|
|
|
|
lk.unlock(); |
|
|
|
|
|
} |
|
|
#ifdef SANITY_CHECK
|
|
|
#ifdef SANITY_CHECK
|
|
|
if (signalAssigned[sIdx] == false) { |
|
|
if (signalAssigned[sIdx] == false) { |
|
|
fprintf(stderr, "Accessing a not assigned signal: %d\n", sIdx); |
|
|
fprintf(stderr, "Accessing a not assigned signal: %d\n", sIdx); |
|
@ -129,9 +156,25 @@ void Circom_CalcWit::getSignal(int cIdx, int sIdx, PBigInt value) { |
|
|
} |
|
|
} |
|
|
#endif
|
|
|
#endif
|
|
|
mpz_set(*value, signalValues[sIdx]); |
|
|
mpz_set(*value, signalValues[sIdx]); |
|
|
|
|
|
/*
|
|
|
|
|
|
char *valueStr = mpz_get_str(0, 10, *value); |
|
|
|
|
|
syncPrintf("%d, Get %d --> %s\n", currentComponentIdx, sIdx, valueStr); |
|
|
|
|
|
free(valueStr); |
|
|
|
|
|
*/ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Circom_CalcWit::finished(int cIdx) { |
|
|
|
|
|
{ |
|
|
|
|
|
std::lock_guard<std::mutex> lk(mutexes[cIdx % NMUTEXES]); |
|
|
|
|
|
inputSignalsToTrigger[cIdx] = -1; |
|
|
|
|
|
} |
|
|
|
|
|
// syncPrintf("Finished: %d\n", cIdx);
|
|
|
|
|
|
cvs[cIdx % NMUTEXES].notify_all(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Circom_CalcWit::setSignal(int cIdx, int sIdx, PBigInt value) { |
|
|
|
|
|
|
|
|
void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value) { |
|
|
|
|
|
// syncPrintf("setSignal: %d\n", sIdx);
|
|
|
|
|
|
|
|
|
#ifdef SANITY_CHECK
|
|
|
#ifdef SANITY_CHECK
|
|
|
if (signalAssigned[sIdx] == true) { |
|
|
if (signalAssigned[sIdx] == true) { |
|
|
fprintf(stderr, "Signal assigned twice: %d\n", sIdx); |
|
|
fprintf(stderr, "Signal assigned twice: %d\n", sIdx); |
|
@ -139,46 +182,68 @@ void Circom_CalcWit::setSignal(int cIdx, int sIdx, PBigInt value) { |
|
|
} |
|
|
} |
|
|
signalAssigned[sIdx] = true; |
|
|
signalAssigned[sIdx] = true; |
|
|
#endif
|
|
|
#endif
|
|
|
/*
|
|
|
|
|
|
// Log assignement
|
|
|
// Log assignement
|
|
|
|
|
|
/*
|
|
|
char *valueStr = mpz_get_str(0, 10, *value); |
|
|
char *valueStr = mpz_get_str(0, 10, *value); |
|
|
printf("%d --> %s\n", sIdx, valueStr); |
|
|
|
|
|
|
|
|
syncPrintf("%d, Set %d --> %s\n", currentComponentIdx, sIdx, valueStr); |
|
|
free(valueStr); |
|
|
free(valueStr); |
|
|
*/ |
|
|
*/ |
|
|
mpz_set(signalValues[sIdx], *value); |
|
|
mpz_set(signalValues[sIdx], *value); |
|
|
if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) { |
|
|
if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) { |
|
|
inputSignalsToTrigger[cIdx]--; |
|
|
|
|
|
if (inputSignalsToTrigger[cIdx] == 0) triggerComponent(cIdx); |
|
|
|
|
|
|
|
|
if (inputSignalsToTrigger[cIdx]>0) { |
|
|
|
|
|
inputSignalsToTrigger[cIdx]--; |
|
|
|
|
|
if (inputSignalsToTrigger[cIdx] == 0) triggerComponent(cIdx); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Circom_CalcWit::checkConstraint(PBigInt value1, PBigInt value2, char const *err) { |
|
|
|
|
|
|
|
|
void Circom_CalcWit::checkConstraint(int currentComponentIdx, PBigInt value1, PBigInt value2, char const *err) { |
|
|
#ifdef SANITY_CHECK
|
|
|
#ifdef SANITY_CHECK
|
|
|
if (mpz_cmp(*value1, *value2) != 0) { |
|
|
if (mpz_cmp(*value1, *value2) != 0) { |
|
|
char *pcV1 = mpz_get_str(0, 10, *value1); |
|
|
char *pcV1 = mpz_get_str(0, 10, *value1); |
|
|
char *pcV2 = mpz_get_str(0, 10, *value2); |
|
|
char *pcV2 = mpz_get_str(0, 10, *value2); |
|
|
std::string sV1 = std::string(pcV1); |
|
|
|
|
|
std::string sV2 = std::string(pcV2); |
|
|
|
|
|
|
|
|
// throw std::runtime_error(std::to_string(currentComponentIdx) + std::string(", Constraint doesn't match, ") + err + ". " + sV1 + " != " + sV2 );
|
|
|
|
|
|
fprintf(stderr, "Constraint doesn't match, %s: %s != %s", err, pcV1, pcV2); |
|
|
free(pcV1); |
|
|
free(pcV1); |
|
|
free(pcV2); |
|
|
free(pcV2); |
|
|
throw std::runtime_error(std::string("Constraint doesn't match, ") + err + ". " + sV1 + " != " + sV2 ); |
|
|
|
|
|
|
|
|
assert(false); |
|
|
} |
|
|
} |
|
|
#endif
|
|
|
#endif
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Circom_CalcWit::triggerComponent(int newCIdx) { |
|
|
void Circom_CalcWit::triggerComponent(int newCIdx) { |
|
|
int oldCIdx = cIdx; |
|
|
|
|
|
cIdx = newCIdx; |
|
|
|
|
|
(*(circuit->components[newCIdx].fn))(this); |
|
|
|
|
|
cIdx = oldCIdx; |
|
|
|
|
|
|
|
|
//int oldCIdx = cIdx;
|
|
|
|
|
|
// cIdx = newCIdx;
|
|
|
|
|
|
if (circuit->components[newCIdx].newThread) { |
|
|
|
|
|
// syncPrintf("Triggered: %d\n", newCIdx);
|
|
|
|
|
|
std::thread t(circuit->components[newCIdx].fn, this, newCIdx); |
|
|
|
|
|
// t.join();
|
|
|
|
|
|
t.detach(); |
|
|
|
|
|
} else { |
|
|
|
|
|
(*(circuit->components[newCIdx].fn))(this, newCIdx); |
|
|
|
|
|
} |
|
|
|
|
|
// cIdx = oldCIdx;
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Circom_CalcWit::log(PBigInt value) { |
|
|
void Circom_CalcWit::log(PBigInt value) { |
|
|
char *pcV = mpz_get_str(0, 10, *value); |
|
|
char *pcV = mpz_get_str(0, 10, *value); |
|
|
printf("Log: %s\n", pcV); |
|
|
|
|
|
|
|
|
syncPrintf("Log: %s\n", pcV); |
|
|
free(pcV); |
|
|
free(pcV); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Circom_CalcWit::join() { |
|
|
|
|
|
for (int i=0; i<circuit->NComponents; i++) { |
|
|
|
|
|
std::unique_lock<std::mutex> lk(mutexes[i % NMUTEXES]); |
|
|
|
|
|
while (inputSignalsToTrigger[i] != -1) { |
|
|
|
|
|
cvs[i % NMUTEXES].wait(lk); |
|
|
|
|
|
} |
|
|
|
|
|
// cvs[i % NMUTEXES].wait(lk, [&]{return inputSignalsToTrigger[i] == -1;});
|
|
|
|
|
|
lk.unlock(); |
|
|
|
|
|
// syncPrintf("Joined: %d\n", i);
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|