Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VAN-521] implement a case of mapped to indexed location conversion #40

Merged
merged 1 commit into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions circom/tests/subcmps/conv_map2idx_A.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pragma circom 2.0.3;

// REQUIRES: circom
// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s

template GetWeight(A) {
signal input inp;
}

template ComputeValue() {
component getWeights[2];

getWeights[0] = GetWeight(0);
getWeights[0].inp <-- 888;

getWeights[1] = GetWeight(1);
getWeights[1].inp <-- 999;
}

component main = ComputeValue();
23 changes: 23 additions & 0 deletions circom/tests/subcmps/conv_map2idx_B.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma circom 2.0.3;

// REQUIRES: circom
// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s

template GetWeight(A, B) {
signal output x; //signal index 0
signal output y; //signal index 1
signal output out; //signal index 2
out <-- A;
}

template ComputeValue() {
component ws[2];
ws[0] = GetWeight(999, 0);
ws[1] = GetWeight(888, 1);

signal ret[2];
ret[0] <== ws[0].out;
ret[1] <== ws[1].out;
}

component main = ComputeValue();
33 changes: 16 additions & 17 deletions circuit_passes/src/bucket_interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,22 +243,22 @@ impl<'a> BucketInterpreter<'a> {
(idx.expect("Indexed location must produce a value!").get_u32(), env)
},
LocationRule::Mapped { signal_code, indexes } => {
let mut indexes_values = vec![];
let mut acc_env = env;
for i in indexes {
let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}
let map_access = self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code].offset;
if indexes.len() > 0 {
let map_access = &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code].offset;
let mut indexes_values = vec![];
for i in indexes {
let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}
if indexes.len() == 1 {
(map_access + indexes_values[0], acc_env)
} else {
todo!()
}
} else {
unreachable!()
(map_access, acc_env)
}
}
};
Expand Down Expand Up @@ -316,24 +316,23 @@ impl<'a> BucketInterpreter<'a> {
(idx.expect("Indexed location must produce a value!").get_u32(), env, template_header.clone())
},
LocationRule::Mapped { signal_code, indexes } => {
let mut indexes_values = vec![];
let mut acc_env = env;
for i in indexes {
let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}
let name = Some(acc_env.get_subcmp_name(addr).clone());
let map_access = self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code].offset;
if indexes.len() > 0 {
//eprintln!("IO MAP crashes ({addr}): {:?}", self.io_map.contains_key(&1));
let map_access = &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code].offset;
let mut indexes_values = vec![];
for i in indexes {
let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}
if indexes.len() == 1 {
(map_access + indexes_values[0], acc_env, name)
} else {
todo!()
}
} else {
unreachable!()
(map_access, acc_env, name)
}
}
};
Expand Down
33 changes: 21 additions & 12 deletions circuit_passes/src/passes/mapped_to_indexed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::BTreeMap;
use compiler::circuit_design::template::TemplateCode;
use compiler::compiler_interface::Circuit;
use compiler::intermediate_representation::ir_interface::*;
use compiler::intermediate_representation::{InstructionPointer, UpdateId};
use crate::bucket_interpreter::env::Env;
use crate::bucket_interpreter::observer::InterpreterObserver;
use crate::bucket_interpreter::value::Value::KnownU32;
Expand Down Expand Up @@ -32,26 +33,32 @@ impl MappedToIndexedPass {
.expect("cmp_address instruction in SubcmpSignal must produce a value!")
.get_u32();

let name = acc_env.get_subcmp_name(resolved_addr).clone();
let mut indexes_values = vec![];
let mut acc_env = acc_env;
for i in indexes {
let (val, new_env) = interpreter.execute_instruction(i, acc_env, false);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}

let name = acc_env.get_subcmp_name(resolved_addr).clone();
let map_access = mem.io_map[&acc_env.get_subcmp_template_id(resolved_addr)][signal_code].offset;
if indexes.len() > 0 {
let mut indexes_values = vec![];
for i in indexes {
let (val, new_env) = interpreter.execute_instruction(i, acc_env, false);
indexes_values.push(val.expect("Mapped location must produce a value!").get_u32());
acc_env = new_env;
}
if indexes.len() == 1 {
let map_access = &mem.io_map[&acc_env.get_subcmp_template_id(resolved_addr)][signal_code].offset;
let value = map_access + indexes_values[0];
let mut unused = vec![];
LocationRule::Indexed { location: KnownU32(value).to_value_bucket(&mut unused).allocate(), template_header: Some(name) }
LocationRule::Indexed {
location: KnownU32(value).to_value_bucket(&mut unused).allocate(),
template_header: Some(name),
}
} else {
todo!()
}
} else {
unreachable!()
let mut unused = vec![];
LocationRule::Indexed {
location: KnownU32(map_access).to_value_bucket(&mut unused).allocate(),
template_header: Some(name),
}
}
}

Expand Down Expand Up @@ -159,7 +166,9 @@ impl CircuitTransformationPass for MappedToIndexedPass {
fn transform_location_rule(&self, location_rule: &LocationRule) -> LocationRule {
// If the interpreter found a viable transformation, do that.
if let Some(indexed_rule) = self.replacements.borrow().get(&location_rule) {
return indexed_rule.clone();
let mut clone = indexed_rule.clone();
clone.update_id(); //generate a new unique ID for the clone to avoid assertion in checks.rs
return clone;
}
match location_rule {
LocationRule::Indexed { location, template_header } => LocationRule::Indexed {
Expand Down
Loading