mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Store record batches in caller-owned frame buffers instead of aliased stack pointers
This commit is contained in:
@@ -457,6 +457,42 @@ mod tests {
|
||||
assert_eq!(unsafe { out.rec(&value).element::<f64>() }, 21.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reducer_folds_varying_copies_of_a_generic_repeat() {
|
||||
let arena = Arena::new(1024).unwrap();
|
||||
let generations = [];
|
||||
let scope = scope_fixture(&generations, &arena);
|
||||
let ctx = ContextImpl::root(&scope);
|
||||
|
||||
let base = f64_layout(&[]);
|
||||
let (count_edge, count_layout) = lifted_value(4u32);
|
||||
let out = f64_layout(&[]);
|
||||
reserve_for(&[&base, &count_layout, &out]);
|
||||
|
||||
let meta = core_types::record::LayoutMeta {
|
||||
sources: vec![0],
|
||||
reads: vec![],
|
||||
element: core_types::record::ElementSpec::Carried,
|
||||
writes: vec![],
|
||||
removes: vec![],
|
||||
level_delta: 1,
|
||||
};
|
||||
let repeat = install(
|
||||
RepeatNode::new(RecordSource::new(IndexSourceNode { layout: base.clone() }, &base, &base), count_edge, &base, &count_layout),
|
||||
meta,
|
||||
&[Some(&base)],
|
||||
);
|
||||
let leveled = Node::<ContextImpl>::layout(&repeat).clone();
|
||||
let node = install_flip(SumNode::new(repeat, &leveled), &out);
|
||||
|
||||
let GPoll::Final(value) = node.eval(&ctx) else {
|
||||
panic!("expected a final record");
|
||||
};
|
||||
// Every copy evaluates at its own index, so the lanes must be distinct
|
||||
// storage: sum(0 + 1 + 2 + 3), not four aliases of the last copy.
|
||||
assert_eq!(unsafe { out.rec(&value).element::<f64>() }, 6.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layout_meta_folds_to_construction() {
|
||||
let base = f64_layout(&[]);
|
||||
|
||||
@@ -1140,13 +1140,14 @@ mod graphene_test {
|
||||
reserve_for(&[&li, &ls, &out]);
|
||||
|
||||
let erased: Box<ErasedRecordNode> = Box::new(node);
|
||||
// One u64 word per lane: the uninstalled layout keeps the f64 inline.
|
||||
let mut scratch = [const { MaybeUninit::uninit() }; 4];
|
||||
let status = erased.eval_batch(&ctx, 2..6, Some(&mut scratch));
|
||||
let BatchStatus::Filled(batch, finality) = status else {
|
||||
panic!("expected filled, got {status:?}");
|
||||
};
|
||||
let mut got = Vec::new();
|
||||
batch.for_each(|_, lane| got.push(unsafe { lane.element::<f64>() }));
|
||||
batch.share().for_each(|_, lane| got.push(unsafe { lane.element::<f64>() }));
|
||||
assert_eq!(got, vec![12.0, 13.0, 14.0, 15.0]);
|
||||
assert_eq!(finality, Finality::AllFinal);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user