diff --git a/examples/C/mpc/benchmarks/db/db_join.c b/examples/C/mpc/benchmarks/db/db_join.c index 4c5494ce..6bd1ae53 100644 --- a/examples/C/mpc/benchmarks/db/db_join.c +++ b/examples/C/mpc/benchmarks/db/db_join.c @@ -2,8 +2,8 @@ * Example on how to merge two data sets and to perform various analyses */ -#define LEN_A 4 -#define LEN_B 4 +#define LEN_A 5 +#define LEN_B 5 #define ATT_A 2 //Number of attributes #define ATT_B 2 @@ -96,12 +96,12 @@ int main(__attribute__((private(0))) int a[LEN_A*ATT_A], __attribute__((private( // merge databases res.joined = cross_join(db, INPUT_A.db, INPUT_B.db); - // if(res.joined >= LEN_A*LEN_B) { // Limits the last element - // res.joined = LEN_A*LEN_B-1; - // } - // db[LEN_A*LEN_B*ATT] = res.joined; - // res.analysis1 = agg_mean_tree(db, LEN_A*LEN_B, ATT); - // res.analysis2 = res.analysis1; - // // res.analysis2 = variance(db, LEN_A*LEN_B); + if(res.joined >= LEN_A*LEN_B) { // Limits the last element + res.joined = LEN_A*LEN_B-1; + } + db[LEN_A*LEN_B*ATT] = res.joined; + res.analysis1 = agg_mean_tree(db, LEN_A*LEN_B, ATT); + res.analysis2 = res.analysis1; + // res.analysis2 = variance(db, LEN_A*LEN_B); return res.joined + res.analysis1 + res.analysis2; } diff --git a/scripts/aby_tests/c_test_aby.py b/scripts/aby_tests/c_test_aby.py index f1917d5f..6ab5ce80 100755 --- a/scripts/aby_tests/c_test_aby.py +++ b/scripts/aby_tests/c_test_aby.py @@ -4,32 +4,32 @@ from util import run_tests from test_suite import * if __name__ == "__main__": - tests = arithmetic_tests + \ - arithmetic_boolean_tests + \ - nary_arithmetic_tests + \ - bitwise_tests + \ - boolean_tests + \ - nary_boolean_tests + \ - const_arith_tests + \ - const_bool_tests + \ - ite_tests + \ - shift_tests + \ - div_tests + \ - mod_tests + \ - array_tests + \ - c_array_tests + \ - function_tests + \ - struct_tests + \ - matrix_tests + \ - ptr_tests + \ - c_misc_tests + \ - biomatch_tests + \ - kmeans_tests_2 + \ - gauss_tests + # tests = arithmetic_tests + \ + # arithmetic_boolean_tests + \ + # nary_arithmetic_tests + \ + # bitwise_tests + \ + # boolean_tests + \ + # nary_boolean_tests + \ + # const_arith_tests + \ + # const_bool_tests + \ + # ite_tests + \ + # shift_tests + \ + # div_tests + \ + # mod_tests + \ + # array_tests + \ + # c_array_tests + \ + # function_tests + \ + # struct_tests + \ + # matrix_tests + \ + # ptr_tests + \ + # c_misc_tests + \ + # biomatch_tests + \ + # kmeans_tests_2 + \ + # gauss_tests # tests = biomatch_tests - # tests = db_tests + tests = db_tests # TODO: add support for return value - int promotion # unsigned_arithmetic_tests + \ diff --git a/scripts/aby_tests/test_inputs/db_join.txt b/scripts/aby_tests/test_inputs/db_join.txt index bd31be51..453d9cb8 100644 --- a/scripts/aby_tests/test_inputs/db_join.txt +++ b/scripts/aby_tests/test_inputs/db_join.txt @@ -1,3 +1,3 @@ -a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -b 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -res 50 \ No newline at end of file +a 0 1 2 3 4 5 6 7 8 9 +b 0 1 2 3 4 5 6 7 8 9 +res 25 \ No newline at end of file diff --git a/src/target/aby/trans.rs b/src/target/aby/trans.rs index 660de971..baf46ba4 100644 --- a/src/target/aby/trans.rs +++ b/src/target/aby/trans.rs @@ -110,7 +110,7 @@ impl<'a> ToABY<'a> { fn write_const_output(&mut self, flush: bool) { if flush || self.const_output.len() >= WRITE_SIZE { - let const_output_path = get_path(self.path, &self.lang, "const"); + let const_output_path = get_path(self.path, &self.lang, "const", false); write_lines(&const_output_path, &self.const_output); self.const_output.clear(); } @@ -122,6 +122,7 @@ impl<'a> ToABY<'a> { self.path, &self.lang, &format!("{}_bytecode_output", self.curr_comp), + false, ); write_lines(&bytecode_output_path, &self.bytecode_output); self.bytecode_output.clear(); @@ -130,84 +131,84 @@ impl<'a> ToABY<'a> { fn write_share_output(&mut self, flush: bool) { if flush || self.share_output.len() >= WRITE_SIZE { - let share_output_path = get_path(self.path, &self.lang, "share_map"); + let share_output_path = get_path(self.path, &self.lang, "share_map", false); write_lines(&share_output_path, &self.share_output); self.share_output.clear(); } } - fn map_to_shares(&mut self) { - let mut now = Instant::now(); - let computations = self.fs.computations.clone(); - println!("Time: cloning computations: {:?}", now.elapsed()); + // fn map_to_shares(&mut self) { + // let mut now = Instant::now(); + // let computations = self.fs.computations.clone(); + // println!("Time: cloning computations: {:?}", now.elapsed()); - let mut term_to_share_time: std::time::Duration = std::time::Duration::new(0, 0); - let mut write_line_time: std::time::Duration = std::time::Duration::new(0, 0); - let mut create_line_time: std::time::Duration = std::time::Duration::new(0, 0); - let mut format_line_time: std::time::Duration = std::time::Duration::new(0, 0); - let mut add_line_time: std::time::Duration = std::time::Duration::new(0, 0); + // let mut term_to_share_time: std::time::Duration = std::time::Duration::new(0, 0); + // let mut write_line_time: std::time::Duration = std::time::Duration::new(0, 0); + // let mut create_line_time: std::time::Duration = std::time::Duration::new(0, 0); + // let mut format_line_time: std::time::Duration = std::time::Duration::new(0, 0); + // let mut add_line_time: std::time::Duration = std::time::Duration::new(0, 0); - let share_map_path = get_path(self.path, &self.lang, "share_map"); - let mut share_outputs = Vec::with_capacity(WRITE_SIZE * 2); - for (name, comp) in computations.iter() { - println!("mapping {} to shares, total terms: {}", name, comp.terms()); - let share_map = self.get_sharing_map(name); - for t in comp.terms_postorder() { - match t.op { - // these cases are handled dynamically by updating the base array share - Op::Field(..) | Op::Update(..) | Op::Select | Op::Store | Op::Tuple => continue, - _ => {} - } + // let share_map_path = get_path(self.path, &self.lang, "share_map"); + // let mut share_outputs = Vec::with_capacity(WRITE_SIZE * 2); + // for (name, comp) in computations.iter() { + // println!("mapping {} to shares, total terms: {}", name, comp.terms()); + // let share_map = self.get_sharing_map(name); + // for t in comp.terms_postorder() { + // match t.op { + // // these cases are handled dynamically by updating the base array share + // Op::Field(..) | Op::Update(..) | Op::Select | Op::Store | Op::Tuple => continue, + // _ => {} + // } - now = Instant::now(); - let sort: Sort = check(&t); - let num_shares = self.get_sort_len(&sort) as i32; - let shares: Vec = (0..num_shares) - .map(|x| x + self.share_cnt) - .collect::>(); - self.share_cnt += num_shares; - self.term_to_shares.insert(t.clone(), shares.clone()); - term_to_share_time += now.elapsed(); + // now = Instant::now(); + // let sort: Sort = check(&t); + // let num_shares = self.get_sort_len(&sort) as i32; + // let shares: Vec = (0..num_shares) + // .map(|x| x + self.share_cnt) + // .collect::>(); + // self.share_cnt += num_shares; + // self.term_to_shares.insert(t.clone(), shares.clone()); + // term_to_share_time += now.elapsed(); - now = Instant::now(); - // write sharing map - let share_type = share_map.get(&t).unwrap(); - let share_str = share_type.char(); - create_line_time += now.elapsed(); + // now = Instant::now(); + // // write sharing map + // let share_type = share_map.get(&t).unwrap(); + // let share_str = share_type.char(); + // create_line_time += now.elapsed(); - for s in shares { - now = Instant::now(); - let line = format!("{} {}\n", s, share_str); - format_line_time += now.elapsed(); + // for s in shares { + // now = Instant::now(); + // let line = format!("{} {}\n", s, share_str); + // format_line_time += now.elapsed(); - now = Instant::now(); - share_outputs.push(line); - add_line_time += now.elapsed(); - } + // now = Instant::now(); + // share_outputs.push(line); + // add_line_time += now.elapsed(); + // } - now = Instant::now(); - // buffered write - if share_outputs.len() >= WRITE_SIZE { - write_lines(&share_map_path, &share_outputs); - share_outputs.clear(); - } - write_line_time += now.elapsed(); - } + // now = Instant::now(); + // // buffered write + // if share_outputs.len() >= WRITE_SIZE { + // write_lines(&share_map_path, &share_outputs); + // share_outputs.clear(); + // } + // write_line_time += now.elapsed(); + // } - self.s_map.remove(name); - } + // self.s_map.remove(name); + // } - write_lines(&share_map_path, &share_outputs); + // write_lines(&share_map_path, &share_outputs); - // clear share map - self.s_map.clear(); + // // clear share map + // self.s_map.clear(); - println!("term to share time: {:?}", term_to_share_time); - println!("create time: {:?}", create_line_time); - println!("format time: {:?}", format_line_time); - println!("add time: {:?}", add_line_time); - println!("write time: {:?}", write_line_time); - } + // println!("term to share time: {:?}", term_to_share_time); + // println!("create time: {:?}", create_line_time); + // println!("format time: {:?}", format_line_time); + // println!("add time: {:?}", add_line_time); + // println!("write time: {:?}", write_line_time); + // } fn get_md(&self) -> ComputationMetadata { self.fs @@ -862,9 +863,23 @@ impl<'a> ToABY<'a> { /// Given a term `t`, lower `t` to ABY Circuits fn lower(&mut self) { let computations = self.fs.computations.clone(); + + // create output files + get_path(self.path, &self.lang, "const", true); + get_path(self.path, &self.lang, "share_map", true); + for (name, comp) in computations.iter() { let mut outputs: Vec = Vec::new(); let mut now = Instant::now(); + + // create paths + get_path( + self.path, + &self.lang, + &format!("{}_bytecode_output", name), + true, + ); + for t in comp.outputs.iter() { self.curr_comp = name.to_string(); self.embed(t.clone()); @@ -914,13 +929,19 @@ impl<'a> ToABY<'a> { now = Instant::now(); // write input bytecode - let bytecode_path = get_path(self.path, &self.lang, &format!("{}_bytecode", name)); + let bytecode_path = + get_path(self.path, &self.lang, &format!("{}_bytecode", name), true); write_lines(&bytecode_path, &self.bytecode_input); // write output bytecode - let bytecode_output_path = - get_path(self.path, &self.lang, &format!("{}_bytecode_output", name)); + let bytecode_output_path = get_path( + self.path, + &self.lang, + &format!("{}_bytecode_output", name), + false, + ); write_lines(&bytecode_output_path, &self.bytecode_output); + println!("writing to bytecode output"); println!("Time: writing {}: {:?}", name, now.elapsed()); diff --git a/src/target/aby/utils.rs b/src/target/aby/utils.rs index 689d3ce2..3363b532 100644 --- a/src/target/aby/utils.rs +++ b/src/target/aby/utils.rs @@ -1,8 +1,8 @@ //! Utility functions to write compiler output to ABY use std::env; -use std::fs; -use std::io::prelude::*; +use std::fs::{self, File, OpenOptions}; +use std::io::Write; use std::path::Path; /// Get ABY source directory @@ -15,7 +15,7 @@ pub fn get_aby_source() -> String { } /// Given Path `path` and String denominator `lang`, return the filename of the path -pub fn get_path(path: &Path, lang: &str, t: &str) -> String { +pub fn get_path(path: &Path, lang: &str, t: &str, create: bool) -> String { let filename = Path::new(&path.iter().last().unwrap()) .file_stem() .unwrap() @@ -31,28 +31,19 @@ pub fn get_path(path: &Path, lang: &str, t: &str) -> String { }; let file_path = format!("{}/{}_{}.txt", dir_path, name, t); - match fs::File::create(&file_path) { - Err(why) => panic!("couldn't create {}: {}", file_path, why), - Ok(file) => file, - }; + if create { + match File::create(&file_path) { + Err(why) => panic!("couldn't create {}: {}", file_path, why), + Ok(file) => file, + }; + } file_path } -/// Write lines to a path -pub fn write_l(file: &mut fs::File, path: &str, lines: &[String]) { - let data = lines.join(""); - file.write_all(data.as_bytes()) - .expect(&format!("Failed to write to file: {}", path)); -} - /// Write lines to a path pub fn write_lines(path: &str, lines: &[String]) { - if !Path::new(&path).exists() { - fs::File::create(&path).expect(&*format!("Failed to create: {}", path)); - } - - let mut file = fs::OpenOptions::new() - .write(true) + let mut file = OpenOptions::new() + .create(true) .append(true) .open(&path) .expect(&format!("Failed to open file: {}", path));