use serde::Serialize;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize)]
pub struct ProfileSummary {
network_depth: usize,
total_gates: usize,
pub(crate) network_size: usize,
pub(crate) preprocess_weight: usize,
}
const ONLINE_WEIGHT: usize = 64;
const NETWORK_ROUND_TIME: usize = 1 << 15;
const NETWORK_BYTE_DURATION: usize = 4;
const GATE_TIME: usize = 4;
impl ProfileSummary {
pub fn weight(&self) -> usize {
ONLINE_WEIGHT
* (self.network_depth * NETWORK_ROUND_TIME
+ self.total_gates * GATE_TIME
+ self.network_size * NETWORK_BYTE_DURATION)
+ self.preprocess_weight
}
pub fn weight_js() -> String {
let network_depth_weight = ProfileSummary {
network_depth: 1,
..Default::default()
}
.weight();
let gate_weight = ProfileSummary {
total_gates: 1,
..Default::default()
}
.weight();
let network_size_weight = ProfileSummary {
network_size: 1,
..Default::default()
}
.weight();
format!(
"function weight(x){{ return {} * x.network_depth + {} * x.total_gates + {} * x.network_size + x.preprocess_weight;}}",
network_depth_weight,
gate_weight,
network_size_weight)
}
pub fn new(
network_depth: usize,
total_gates: usize,
network_size: usize,
preprocess_weight: usize,
) -> Self {
Self {
network_depth,
total_gates,
network_size,
preprocess_weight,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use boa_engine::{Context, Source};
#[test]
fn test_weight_javascript() {
fn test_weight_js(profile_summary: ProfileSummary) {
let weight = profile_summary.weight();
let js_code = format!(
"{}\nweight({})",
ProfileSummary::weight_js(),
serde_json::to_string(&profile_summary).expect("Serialization failed.")
);
let mut context = Context::default();
let result = context
.eval(Source::from_bytes(&js_code))
.expect("Eval failed.");
assert_eq!(result.as_number().unwrap() as usize, weight);
}
test_weight_js(ProfileSummary::new(5, 0, 0, 0));
test_weight_js(ProfileSummary::new(0, 9, 0, 0));
test_weight_js(ProfileSummary::new(0, 0, 13, 0));
test_weight_js(ProfileSummary::new(0, 0, 0, 17));
test_weight_js(ProfileSummary::new(1, 2, 3, 4));
test_weight_js(ProfileSummary::new(4, 3, 2, 1));
}
}