use crate::active_set::*;
use crate::warp::Warp;
pub fn merge<S1, S2>(_left: Warp<S1>, _right: Warp<S2>) -> Warp<All>
where
S1: ComplementOf<S2>,
S2: ActiveSet,
{
Warp::new()
}
pub fn merge_within<S1, S2, P>(_left: Warp<S1>, _right: Warp<S2>) -> Warp<P>
where
S1: ComplementWithin<S2, P>,
S2: ActiveSet,
P: ActiveSet,
{
Warp::new()
}
pub fn with_diverged<S1, S2, A, F1, F2>(
_warp: Warp<All>,
then_fn: F1,
else_fn: F2,
) -> (A, A, Warp<All>)
where
S1: ActiveSet + ComplementOf<S2>,
S2: ActiveSet + ComplementOf<S1>,
F1: FnOnce(Warp<S1>) -> A,
F2: FnOnce(Warp<S2>) -> A,
{
let then_result = then_fn(Warp::new());
let else_result = else_fn(Warp::new());
(then_result, else_result, Warp::new())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merge_even_odd() {
let all: Warp<All> = Warp::new();
let (evens, odds) = all.diverge_even_odd();
let merged: Warp<All> = merge(evens, odds);
assert_eq!(merged.active_set_name(), "All");
}
#[test]
fn test_merge_halves() {
let all: Warp<All> = Warp::new();
let (low, high) = all.diverge_halves();
let merged = merge(low, high);
assert_eq!(merged.active_mask(), All::MASK);
}
#[test]
fn test_merge_lane0() {
let all: Warp<All> = Warp::new();
let (lane0, rest) = all.extract_lane0();
let merged = merge(lane0, rest);
assert_eq!(merged.population(), crate::WARP_SIZE);
}
#[test]
fn test_nested_merge() {
let all: Warp<All> = Warp::new();
let (evens, odds) = all.diverge_even_odd();
let (even_low, even_high) = evens.diverge_halves();
let evens_restored: Warp<Even> = merge_within(even_low, even_high);
assert_eq!(evens_restored.active_set_name(), "Even");
let all_restored = merge(evens_restored, odds);
assert_eq!(all_restored.active_set_name(), "All");
}
#[test]
fn test_merge_ordering_equivalence() {
let el1: Warp<EvenLow> = Warp::new();
let eh1: Warp<EvenHigh> = Warp::new();
let ol1: Warp<OddLow> = Warp::new();
let oh1: Warp<OddHigh> = Warp::new();
let even: Warp<Even> = merge_within(el1, eh1);
let odd: Warp<Odd> = merge_within(ol1, oh1);
let result1 = merge(even, odd);
let el2: Warp<EvenLow> = Warp::new();
let eh2: Warp<EvenHigh> = Warp::new();
let ol2: Warp<OddLow> = Warp::new();
let oh2: Warp<OddHigh> = Warp::new();
let low: Warp<LowHalf> = merge_within(el2, ol2);
let high: Warp<HighHalf> = merge_within(eh2, oh2);
let result2 = merge(low, high);
assert_eq!(result1.population(), crate::WARP_SIZE);
assert_eq!(result2.population(), crate::WARP_SIZE);
}
#[test]
fn test_full_pipeline_nested_diverge_to_shuffle() {
let warp: Warp<All> = Warp::kernel_entry();
let (evens, odds) = warp.diverge_even_odd();
let (even_low, even_high) = evens.diverge_halves();
let evens_restored: Warp<Even> = merge_within(even_low, even_high);
let all_restored: Warp<All> = merge(evens_restored, odds);
let data = crate::data::PerLane::new(1i32);
let result = all_restored.shuffle_xor(data, 1);
assert_eq!(result.get(), 1); let sum = all_restored.reduce_sum(data);
assert_eq!(sum.get(), crate::WARP_SIZE as i32);
}
#[test]
fn test_with_diverged() {
let warp: Warp<All> = Warp::new();
let (a, b, merged) = with_diverged::<Even, Odd, i32, _, _>(warp, |_| 100, |_| 200);
assert_eq!(a, 100);
assert_eq!(b, 200);
assert_eq!(merged.population(), crate::WARP_SIZE);
}
}