use crate::custom_ops::CustomOperation;
use crate::data_types::{array_type, ScalarType, BIT};
use crate::errors::Result;
use crate::graphs::{Context, Graph, SliceElement};
use crate::ops::min_max::Min;
pub fn create_minimum_graph(context: Context, n: u64, st: ScalarType) -> Result<Graph> {
let signed_comparison = st.is_signed();
let g = context.create_graph()?;
let input_type = array_type(vec![1 << n], st);
let input_array = g.input(input_type)?;
let mut binary_array = if st != BIT {
input_array.a2b()?
} else {
input_array
};
for level in (0..n).rev() {
let half1 =
binary_array.get_slice(vec![SliceElement::SubArray(None, Some(1 << level), None)])?;
let half2 =
binary_array.get_slice(vec![SliceElement::SubArray(Some(1 << level), None, None)])?;
binary_array = g.custom_op(
CustomOperation::new(Min { signed_comparison }),
vec![half1, half2],
)?;
}
let output = if st != BIT {
binary_array.b2a(st)?
} else {
binary_array
};
output.set_as_output()?;
g.finalize()?;
Ok(g)
}
#[cfg(test)]
mod tests {
use crate::custom_ops::run_instantiation_pass;
use crate::data_types::{INT32, UINT32};
use crate::data_values::Value;
use crate::evaluators::random_evaluate;
use crate::graphs::create_context;
use std::ops::Not;
use super::*;
fn test_minimum_helper<T: TryInto<u128> + Not<Output = T> + TryInto<u8> + Copy>(
input_value: &[T],
n: u64,
st: ScalarType,
) -> Value {
|| -> Result<Value> {
let c = create_context()?;
let g = create_minimum_graph(c.clone(), n, st)?;
g.set_as_main()?;
c.finalize()?;
let mapped_c = run_instantiation_pass(c)?.get_context();
let mapped_g = mapped_c.get_main_graph()?;
let input_type = array_type(vec![n], st);
let val = Value::from_flattened_array(input_value, input_type.get_scalar_type())?;
random_evaluate(mapped_g, vec![val])
}()
.unwrap()
}
#[test]
fn test_minimum() {
|| -> Result<()> {
assert!(
test_minimum_helper(
&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
4,
UINT32
) == Value::from_flattened_array(&[1], UINT32)?
);
Ok(())
}()
.unwrap();
|| -> Result<()> {
assert!(
test_minimum_helper(
&[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16],
4,
INT32
) == Value::from_flattened_array(&[-15], INT32)?
);
Ok(())
}()
.unwrap();
|| -> Result<()> {
assert!(
test_minimum_helper(&[0, 1, 1, 0, 1, 1, 0, 0], 3, BIT)
== Value::from_flattened_array(&[0], BIT)?
);
Ok(())
}()
.unwrap();
}
}