How to run a loop with unknown number of iterations in Circom? - circuit

I have the following circuit in Circom cicuit compiler:
pragma circom 2.0.0;
template MAIN() {
signal len;
len <== 32;
for (k = 0; k < maplen; k++) {
// do something
}
}
component main = MAIN();
I'm getting an error:
error[T2005]: Typing error found
┌─ "/Users/ilia/compiling/main-circom/circuits/main.circom":118:17
│
118 │ for (k = 0; k < len; k++) {
│ ^^^^^^^ There are constraints depending on the value of the condition and it can be unknown during the constraint generation phase
How do I write this loop in a way which makes it possible to iterate len times where len is a signal?

You need to decide how many maximum iterations your loop can have (an iteration budget) and then discard all the iterations you don't need using LessThan component. You can also select the needed result of a iteration using QuinSelector

Related

Is it possible to parallelize or unroll this loop?

I am trying to see if I can improve the performance of the following loop in C++, which uses two dimensional vectors (_external and _Table) and has a carried loop dependency on the previous iteration. Additionally, it has a calculated index accessor in the innermost loop that will make the access of _Table non sequential on the right hand side.
int N = 8000;
int M = 400
int P = 100;
for(int i = 1; i <= N; i++){
for(int j = 0; j < M; j++){
for(int k =0; k < P; k++){
int index = _external.at(j).at(k);
_Table.at(j).at(i) += _Table.at(index).at(i-1);
}
}
}
What can I do to improve the performance of a loop like this?
Well it looks to me like the order in which these statements:
int index = _external.at(j).at(k);
_Table.at(j).at(i) += _Table.at(index).at(i-1);
are executed is critical to correctness. (That is, if the iteration order for i, j, k changes, then the results will be different ... and incorrect.)
So I think you are only left with micro-optimizations, like hoisting the expressions _Table.at(j).at(i) and _external.at(j) out of the innermost loop.
Consider this:
for(int k =0; k < P; k++){
int index = _external.at(j).at(k);
_Table.at(j).at(i) += _Table.at(index).at(i-1);
}
This loop is repeatedly adding numbers to _Table.at(j).at(i). Since (by inspection) _Table.at(index).at(i-1) must be reading from a different cell of the table (because of i-1 versus i), you could do this:
int temp = 0;
for(int k =0; k < P; k++){
int index = _external.at(j).at(k);
temp += _Table.at(index).at(i-1);
}
_Table.at(j).at(i) += temp;
This will reduce the number of calls to at, and may also improve cache performance a bit.

Wrapping around negative numbers in Rust

I'm rewriting C code in Rust which heavily relies on u32 variables and wrapping them around. For example, I have a loop defined like this:
#define NWORDS 24
#define ZERO_WORDS 11
int main()
{
unsigned int i, j;
for (i = 0; i < NWORDS; i++) {
for (j = 0; j < i; j++) {
if (j < (i-ZERO_WORDS+1)) {
}
}
}
return 0;
}
Now, the if statement will need to wrap around u32 for a few values as initially i = 0. I came across the wrapping_neg method but it seems to just compute -self. Is there any more flexible way to work with u32 in Rust by also allowing wrapping?
As mentioned in the comments, the literal answer to your question is to use u32::wrapping_sub and u32::wrapping_add:
const NWORDS: u32 = 24;
const ZERO_WORDS: u32 = 11;
fn main() {
for i in 0..NWORDS {
for j in 0..i {
if j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1) {}
}
}
}
However, I'd advocate avoiding relying on wrapping operations unless you are performing hashing / cryptography / compression / something similar. Wrapping operations are non-intuitive. For example, j < i-ZERO_WORDS+1 doesn't have the same results as j+ZERO_WORDS < i+1.
Even better would be to rewrite the logic. I can't even tell in which circumstances that if expression will be true without spending a lot of time thinking about it!
It turns out that the condition will be evaluated for i=9, j=8, but not for i=10, j=0. Perhaps all of this is clearer in the real code, but devoid of context it's very confusing.
This appears to have the same logic, but seems much more understandable to me:
i < ZERO_WORDS - 1 || i - j > ZERO_WORDS - 1;
Compare:
j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1);

OpenMP in Biham-Middleton-Levine BML model

I've got a serial version of BML and I'm trying to write a parallel one with OpenMP. Basically my code works with a main witin a loop calling two functions for horizontal and vertical moves. Like that:
for (s = 0; s < nmovss; s++) {
horizontal_movs(grid, N);
copy_sides(grid, N);
cur = 1-cur;
vertical_movs(grid, N);
copy_sides(grid, N);
cur = 1-cur;
}
Where cur is the current grid. Then horizontal and vertical functions are similar and have a nested loop:
for(i = 1; i <= n; i++) {
for(j = 1; j <= n+1; j++) {
if(grid[cur][i][j-1] == LR && grid[cur][i][j] == EMPTY) {
grid[1-cur][i][j-1] = EMPTY;
grid[1-cur][i][j] = LR;
}
else {
grid[1-cur][i][j] = grid[cur][i][j];
}
}
}
The code produces a ppm image at every step, and whit a certain input the serial version produce an output that we can suppose good. But using #pragma omp parallel for inside the two functions H and V, the ppm file results splitted in such zones as the number of threads(i.e. 4):
I suppose the problem is that every thread should be doing both functions in sequence before termitate because movememnts are strictcly connected. I don't know how to do that. If I set pragma at a highter level like before main loop, there is no speed-up. Obviously the ppm file has to be not sliced like the image.
Goin'on I tried this solution that gives me an identical result as the serial code, but I don't excatly understand why
# pragma omp parallel num_threads(thread_count) default(none) \
shared(grid, n, cur) private(i, j)
for(i = 1; i <= n+1; i++) {
# pragma omp for
for(j = 1; j <= n; j++) {
if(grid[cur][i-1][j] == TB && grid[cur][i][j] == EMPTY) {
grid[1-cur][i-1][j] = EMPTY;
grid[1-cur][i][j] = TB;
}
else {
grid[1-cur][i][j] = grid[cur][i][j];
}
}
}
}
Therefore, if i use just one thread more than available cores(4), the execution time "explodes" instead of remain barely the same.

calculate determinant of matrix with thread

ı want to calculate determinant of matrix with thread but i have a error "term does not eveluate to a function taking 0 arguments" ı want to solve big matrix with thread and parsing matrix,what can ı do
int determinant(int f[1000][1000], int x)
{
int pr, c[1000], d = 0, b[1000][1000], j, p, q, t;
if (x == 2)
{
d = 0;
d = (f[1][1] * f[2][2]) - (f[1][2] * f[2][1]);
return(d);
}
else
{
for (j = 1; j <= x; j++)
{
int r = 1, s = 1;
for (p = 1; p <= x; p++)
{
for (q = 1; q <= x; q++)
{
if (p != 1 && q != j)
{
b[r][s] = f[p][q];
s++;
if (s > x - 1)
{
r++;
s = 1;
}
}
}
}
for (t = 1, pr = 1; t <= (1 + j); t++)
pr = (-1)*pr;
c[j] = pr*determinant(b, x - 1);
}
for (j = 1, d = 0; j <= x; j++)
{
d = d + (f[1][j] * c[j]);
}
return(d);
}
}
int main()
{
srand(time_t(NULL));
int i, j;
printf("\n\nEnter order of matrix : ");
scanf_s("%d", &m);
printf("\nEnter the elements of matrix\n");
for (i = 1; i <= m; i++)
{
for (j = 1; j <= m; j++)
{
a[i][j] = rand() % 10;
}
}
thread t(determinant(a, m));
t.join();
printf("\n Determinant of Matrix A is %d .", determinant(a, m));
}
The immediate problem is that here: thread t(determinant(a, m)); you pass the result of calling determinant(a, m) as the function to execute, and zero arguments to call that function with - but an int is not a function or other callable object, which is what the error you got complains about.
std::thread's constructor takes the function to run and the arguments to supply separately, so you would need to call std::thread(determinant, a, m).
Now we have another problem, std::thread doesn't provide a way to retrieve the return value, and so you calculate it again here: printf("\n Determinant of Matrix A is %d .", determinant(a, m));.
To fix this, we can use std::async from the <future> header, which will manage the thread handling for us, and lets us retrieve the result later:
auto result = std::async(std::launch::async, determinant, a, m);
int det = result.get()
This will run determinant(a,m) on a new thread, and return a std::future<int> into which the return value may eventually be placed.
We can then try to retrieve that value with std::future::get(), which will block until the value can be retrieved (or until an exception occurs in the thread).
In this example, we still execute determinant in a pretty serial fashion, since we delegate the work to a thread, then wait for that thread to finish its work before continuing.
However we are now free to store the future, and defer calling std::future::get() until we actually need the value, potentially much later in your program.
There are a few other problems in the rest of your code:
all your array indexing is off by one (array indices run from 0 to N-1 in C and C++)
a few of the variables you're using don't exist (like a and m)
C-arrays are passed by pointer, so if you ever change the code not to block on the thread right there, the array will go out of scope and your thread may read garbage from the dangling pointer. If you use a proper container like std::array or std::vector, you can pass it by value so your thread will own the data to operate on for its entire lifetime.

correct usage of compare_exchange_weak

const int SIZE = 20;
struct Node { Node* next; };
std::atomic<Node*> head (nullptr);
void push (void* p)
{
Node* n = (Node*) p;
n->next = head.load ();
while (!head.compare_exchange_weak (n->next, n));
}
void* pop ()
{
Node* n = head.load ();
while (n &&
!head.compare_exchange_weak (n, n->next));
return n ? n : malloc (SIZE);
}
void thread_fn()
{
std::array<char*, 1000> pointers;
for (int i = 0; i < 1000; i++) pointers[i] = nullptr;
for (int i = 0; i < 10000000; i++)
{
int r = random() % 1000;
if (pointers[r] != nullptr) // allocated earlier
{
push (pointers[r]);
pointers[r] = nullptr;
}
else
{
pointers[r] = (char*) pop (); // allocate
// stamp the memory
for (int i = 0; i < SIZE; i++)
pointers[r][i] = 0xEF;
}
}
}
int main(int argc, char *argv[])
{
int N = 8;
std::vector<std::thread*> threads;
threads.reserve (N);
for (int i = 0; i < N; i++)
threads.push_back (new std::thread (thread_fn));
for (int i = 0; i < N; i++)
threads[i]->join();
}
What is wrong with this usage of compare_exchange_weak ? The above code crashes 1 in 5 times using clang++ (MacOSX).
The head.load() at the time of the crash will have "0xEFEFEFEFEF". pop is like malloc and push is like free. Each thread (8 threads) randomly allocate or deallocate memory from head
It could be nice lock-free allocator, but ABA-problem arise:
A: Assume, that some thread1 executes pop(), which reads current value of head into n variable, but immediately after this the thread is preemted and concurrent thread2 executes full pop() call, that is it reads same value from head and performs successfull compare_exchange_weak.
B: Now object, referred by n in the thread1, has no longer belonged to the list, and can be modified by thread2. So n->next is garbage in general: reading from it can return any value. For example, it can be 0xEFEFEFEFEF, where the first 5 bytes are stamp (EF), witch has been written by thread2, and the last 3 bytes are still 0, from nullptr. (Total value is numerically interpreted in little-endian manner). It seems that, because head value has been changed, thread1 will fail its compare_exchange_weak call, but...
A: Concurrent thread2 push()es resulted pointer back into the list. So thread1 sees initial value of head, and perform successfull compare_exchange_weak, which writes incorrect value into head. List is corrupted.
Note, that problem is more than possibility, that other thread can modify content of n->next. The problem is that value of n->next is no longer coupled with the list. So, even it is not modified concurrently, it becomes invalid (for replace head) in case, e.g., when other thread(s) pop() 2 elements from the list but push() back only first of them. (So n->next will points to the second element, which is has no longer belonged to the list.)

Resources