Skip to content

Commit

Permalink
WIP manager ordering test
Browse files Browse the repository at this point in the history
  • Loading branch information
imrn99 committed Oct 30, 2024
1 parent fccadad commit 3ceed6c
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 8 deletions.
129 changes: 128 additions & 1 deletion honeycomb-core/src/attributes/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// ------ IMPORTS

use loom::sync::Arc;
use stm::{atomically, StmError, Transaction, TransactionControl};

use super::{
Expand All @@ -16,6 +17,8 @@ use std::any::Any;

// --- basic structure implementation

// vertex bound

#[derive(Clone, Copy, Debug, Default, PartialEq)]
struct Temperature {
pub val: f32,
Expand Down Expand Up @@ -53,7 +56,28 @@ impl From<f32> for Temperature {
}
}

// Create a new edge-bound attribute for testing
#[derive(Debug, Clone, Copy, Default)]
struct Weight(pub u32);

impl AttributeUpdate for Weight {
fn merge(attr1: Self, attr2: Self) -> Self {
Self(attr1.0 + attr2.0)
}

fn split(attr: Self) -> (Self, Self) {
// adding the % to keep things conservative
(Weight(attr.0 / 2 + attr.0 % 2), Weight(attr.0 / 2))
}
}

impl AttributeBind for Weight {
type StorageType = AttrSparseVec<Self>;
type IdentifierType = VertexIdentifier;
const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex;
}

// edge bound

#[derive(Debug, Clone, PartialEq, Copy)]
struct Length(pub f32);

Expand All @@ -73,6 +97,35 @@ impl AttributeBind for Length {
const BIND_POLICY: OrbitPolicy = OrbitPolicy::Edge;
}

// face bound

fn mean(a: u8, b: u8) -> u8 {
((u16::from(a) + u16::from(b)) / 2) as u8
}

#[derive(Debug, Clone, Copy, Default)]
struct Color(pub u8, pub u8, pub u8);

impl AttributeUpdate for Color {
fn merge(attr1: Self, attr2: Self) -> Self {
Self(
mean(attr1.0, attr2.0),
mean(attr1.1, attr2.1),
mean(attr1.2, attr2.2),
)
}

fn split(attr: Self) -> (Self, Self) {
(attr, attr)
}
}

impl AttributeBind for Color {
type StorageType = AttrSparseVec<Self>;
type IdentifierType = FaceIdentifier;
const BIND_POLICY: OrbitPolicy = OrbitPolicy::Face;
}

// --- usual workflow test

#[test]
Expand Down Expand Up @@ -746,3 +799,77 @@ fn manager_split_attribute() {
assert_eq!(manager.get_attribute(6), Some(Temperature::from(289.0)));
assert_eq!(manager.get_attribute::<Temperature>(8), None);
}

// --- parallel
//
#[test]
fn manager_ordering() {
loom::model(|| {
// setup manager
let mut manager = AttrStorageManager::default();
manager.add_storage::<Temperature>(3);
manager.add_storage::<Length>(3);
manager.add_storage::<Weight>(3);
manager.add_storage::<Color>(3);

manager.set_attribute(1, Temperature::from(20.0));
manager.set_attribute(3, Temperature::from(30.0));

manager.set_attribute(1, Length(3.0));
manager.set_attribute(3, Length(2.0));

manager.set_attribute(1, Weight(10));
manager.set_attribute(3, Weight(15));

manager.set_attribute(1, Color(255, 0, 0));
manager.set_attribute(3, Color(0, 0, 255));

let arc = Arc::new(manager);
let c1 = arc.clone();
let c2 = arc.clone();

// we're going to do 2 ops:
// - merge (1, 3) => 2
// - split 2 =< (2, 3)
// depending on the execution path, attribute values on slots 2 and 3 will vary
// attribute value of slot 1 should be None in any case

let t1 = loom::thread::spawn(move || {
atomically(|trans| {
c1.merge_vertex_attributes_transac(trans, 2, 1, 3)?;
c1.merge_edge_attributes_transac(trans, 2, 1, 3)?;
c1.merge_face_attributes_transac(trans, 2, 1, 3)?;
Ok(())
});
});

let t2 = loom::thread::spawn(move || {
atomically(|trans| {
c2.split_vertex_attributes_transac(trans, 2, 3, 2)?;
c2.split_edge_attributes_transac(trans, 2, 3, 2)?;
c2.split_face_attributes_transac(trans, 2, 3, 2)?;
Ok(())
});
});

t1.join().unwrap();
t2.join().unwrap();

// in both cases
let slot_1_is_empty = arc.get_attribute::<Temperature>(1).is_none()
&& arc.get_attribute::<Weight>(1).is_none()
&& arc.get_attribute::<Temperature>(1).is_none()
&& arc.get_attribute::<Color>(1).is_none();
assert!(slot_1_is_empty);

// path 1: merge before split
let p1_2_temp = arc
.get_attribute::<Temperature>(2)
.is_some_and(|val| val == Temperature::from(25.0));
let p1_3_temp = arc
.get_attribute::<Temperature>(3)
.is_some_and(|val| val == Temperature::from(25.0));

// path 2: split before merge
});
}
8 changes: 1 addition & 7 deletions honeycomb-core/src/cmap/dim2/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
attributes::AttrSparseVec,
cmap::{EdgeIdentifier, VertexIdentifier},
cmap::VertexIdentifier,
prelude::{AttributeBind, AttributeUpdate, CMap2, CMapBuilder, Orbit2, OrbitPolicy, Vertex2},
};

Expand Down Expand Up @@ -350,12 +350,6 @@ impl AttributeBind for Weight {
const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex;
}

#[test]
fn merge_ordering() {}

#[test]
fn split_ordering() {}

#[test]
fn sew_ordering() {
loom::model(|| {
Expand Down

0 comments on commit 3ceed6c

Please sign in to comment.