use crate::active_set::*;
use crate::warp::Warp;
impl Warp<All> {
pub fn diverge_even_odd(self) -> (Warp<Even>, Warp<Odd>) {
(Warp::new(), Warp::new())
}
pub fn diverge_halves(self) -> (Warp<LowHalf>, Warp<HighHalf>) {
(Warp::new(), Warp::new())
}
pub fn extract_lane0(self) -> (Warp<Lane0>, Warp<NotLane0>) {
(Warp::new(), Warp::new())
}
}
impl Warp<Even> {
pub fn diverge_halves(self) -> (Warp<EvenLow>, Warp<EvenHigh>) {
(Warp::new(), Warp::new())
}
}
impl Warp<Odd> {
pub fn diverge_halves(self) -> (Warp<OddLow>, Warp<OddHigh>) {
(Warp::new(), Warp::new())
}
}
impl Warp<LowHalf> {
pub fn diverge_even_odd(self) -> (Warp<EvenLow>, Warp<OddLow>) {
(Warp::new(), Warp::new())
}
}
impl Warp<HighHalf> {
pub fn diverge_even_odd(self) -> (Warp<EvenHigh>, Warp<OddHigh>) {
(Warp::new(), Warp::new())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_diverge_even_odd() {
let all: Warp<All> = Warp::new();
let (evens, odds) = all.diverge_even_odd();
assert_eq!(evens.active_set_name(), "Even");
assert_eq!(odds.active_set_name(), "Odd");
assert_eq!(evens.population(), crate::WARP_SIZE / 2);
assert_eq!(odds.population(), crate::WARP_SIZE / 2);
}
#[test]
fn test_diverge_halves() {
let all: Warp<All> = Warp::new();
let (low, high) = all.diverge_halves();
assert_eq!(low.active_mask(), LowHalf::MASK);
assert_eq!(high.active_mask(), HighHalf::MASK);
}
#[test]
fn test_extract_lane0() {
let all: Warp<All> = Warp::new();
let (lane0, rest) = all.extract_lane0();
assert_eq!(lane0.population(), 1);
assert_eq!(rest.population(), crate::WARP_SIZE - 1);
}
#[test]
fn test_nested_diverge_even() {
let all: Warp<All> = Warp::new();
let (evens, _odds) = all.diverge_even_odd();
let (even_low, even_high) = evens.diverge_halves();
assert_eq!(even_low.active_mask(), EvenLow::MASK);
assert_eq!(even_high.active_mask(), EvenHigh::MASK);
assert_eq!(even_low.population(), crate::WARP_SIZE / 4);
assert_eq!(even_high.population(), crate::WARP_SIZE / 4);
}
#[test]
fn test_nested_diverge_odd() {
let all: Warp<All> = Warp::new();
let (_evens, odds) = all.diverge_even_odd();
let (odd_low, odd_high) = odds.diverge_halves();
assert_eq!(odd_low.active_mask(), OddLow::MASK);
assert_eq!(odd_high.active_mask(), OddHigh::MASK);
}
#[test]
fn test_path_independence() {
let all1: Warp<All> = Warp::new();
let (evens, _) = all1.diverge_even_odd();
let (via_even, _) = evens.diverge_halves();
let all2: Warp<All> = Warp::new();
let (low, _) = all2.diverge_halves();
let (via_low, _) = low.diverge_even_odd();
assert_eq!(via_even.active_mask(), via_low.active_mask());
}
}