Update tests, examples, benches

This commit is contained in:
TechnoPorg committed 2026-02-11 22:01:50 +01:00
1 parent 0137296fb4
commit 86787b3a0d
71 files changed
+1791 -3547

No files matched your search

+47 -43
View File
@@ -14,7 +14,7 @@ async fn test_butterfly_network() -> DagResult<()> {
// Layer 0: inputs
let inputs: Vec<_> = (0..8)
.map(|i| {
dag.add_task(task_fn(move |_: ()| async move { i as f64 }))
dag.add_task(task_fn::<(), _, _>(move |_: ()| i as f64))
.into()
})
.collect();
@@ -26,25 +26,29 @@ async fn test_butterfly_network() -> DagResult<()> {
let idx2 = i * 2 + 1;
// Sum operation
layer1.push(
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { (a + b) / 2.0 }))
.depends_on((&inputs[idx1], &inputs[idx2])),
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| {
(a + b) / 2.0
}))
.depends_on((&inputs[idx1], &inputs[idx2])),
);
// Difference operation
layer1.push(
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { (a - b) / 2.0 }))
.depends_on((&inputs[idx1], &inputs[idx2])),
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| {
(a - b) / 2.0
}))
.depends_on((&inputs[idx1], &inputs[idx2])),
);
}
// Layer 2: crossover connections
let layer2: Vec<_> = vec![
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { a + b }))
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| a + b))
.depends_on((&layer1[0], &layer1[4])),
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { a - b }))
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| a - b))
.depends_on((&layer1[1], &layer1[5])),
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { a + b }))
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| a + b))
.depends_on((&layer1[2], &layer1[6])),
dag.add_task(task_fn(|(a, b): (f64, f64)| async move { a - b }))
dag.add_task(task_fn::<(f64, f64), _, _>(|(a, b): (&f64, &f64)| a - b))
.depends_on((&layer1[3], &layer1[7])),
];
@@ -76,11 +80,13 @@ async fn test_recursive_butterfly() -> DagResult<()> {
// Butterfly connections
for i in 0..mid {
let sum = dag
.add_task(task_fn(|(a, b): (i32, i32)| async move { a + b }))
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a + b))
.depends_on((&inputs[i], &inputs[i + mid]));
let diff = dag
.add_task(task_fn(|(a, b): (i32, i32)| async move { (a - b).abs() }))
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| {
(a - b).abs()
}))
.depends_on((&inputs[i], &inputs[i + mid]));
outputs.push(sum);
@@ -94,7 +100,7 @@ async fn test_recursive_butterfly() -> DagResult<()> {
let inputs: Vec<dagx::TaskHandle<i32>> = vec![10, 20, 30, 40]
.into_iter()
.map(|val| {
let task = dag.add_task(task_fn(move |_: ()| async move { val }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| val));
task.into()
})
.collect();
@@ -119,28 +125,36 @@ async fn test_benes_network() -> DagResult<()> {
// 4 inputs
let inputs: Vec<_> = (0..4)
.map(|i| {
dag.add_task(task_fn(move |_: ()| async move { 1 << i }))
dag.add_task(task_fn::<(), _, _>(move |_: ()| 1 << i))
.into()
}) // Powers of 2
.collect();
// First stage: sort pairs
let stage1: Vec<_> = vec![
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a.min(b) }))
.depends_on((&inputs[0], &inputs[1])),
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a.max(b) }))
.depends_on((&inputs[0], &inputs[1])),
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a.min(b) }))
.depends_on((&inputs[2], &inputs[3])),
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a.max(b) }))
.depends_on((&inputs[2], &inputs[3])),
dag.add_task(task_fn::<(i32, i32), _, _>(|(&a, &b): (&i32, &i32)| {
a.min(b)
}))
.depends_on((&inputs[0], &inputs[1])),
dag.add_task(task_fn::<(i32, i32), _, _>(|(&a, &b): (&i32, &i32)| {
a.max(b)
}))
.depends_on((&inputs[0], &inputs[1])),
dag.add_task(task_fn::<(i32, i32), _, _>(|(&a, &b): (&i32, &i32)| {
a.min(b)
}))
.depends_on((&inputs[2], &inputs[3])),
dag.add_task(task_fn::<(i32, i32), _, _>(|(&a, &b): (&i32, &i32)| {
a.max(b)
}))
.depends_on((&inputs[2], &inputs[3])),
];
// Second stage with crossover
let outputs: Vec<_> = vec![
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a | b }))
dag.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a | b))
.depends_on((&stage1[0], &stage1[2])),
dag.add_task(task_fn(|(a, b): (i32, i32)| async move { a | b }))
dag.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a | b))
.depends_on((&stage1[1], &stage1[3])),
];
@@ -162,12 +176,10 @@ async fn test_shuffle_exchange_network() -> DagResult<()> {
let inputs: Vec<TaskHandle<_>> = (0..8)
.map(|i| {
let counter = counter.clone();
dag.add_task(task_fn(move |_: ()| {
dag.add_task(task_fn::<(), _, _>(move |_: ()| {
let counter = counter.clone();
async move {
counter.fetch_add(1, Ordering::Relaxed);
i
}
counter.fetch_add(1, Ordering::Relaxed);
i
}))
.into()
})
@@ -178,7 +190,7 @@ async fn test_shuffle_exchange_network() -> DagResult<()> {
.map(|i| {
// Shuffle pattern: rotate bits
let source = ((i << 1) | (i >> 2)) & 0x7;
dag.add_task(task_fn(move |x: i32| async move { x }))
dag.add_task(task_fn::<i32, _, _>(move |&x: &i32| x))
.depends_on(inputs[source])
})
.collect();
@@ -188,21 +200,13 @@ async fn test_shuffle_exchange_network() -> DagResult<()> {
.flat_map(|i| {
let idx = i * 2;
vec![
dag.add_task(task_fn(|(a, b): (i32, i32)| async move {
if a > b {
b
} else {
a
}
}))
dag.add_task(task_fn::<(i32, i32), _, _>(
|(&a, &b): (&i32, &i32)| if a > b { b } else { a },
))
.depends_on((&shuffled[idx], &shuffled[idx + 1])),
dag.add_task(task_fn(|(a, b): (i32, i32)| async move {
if a > b {
a
} else {
b
}
}))
dag.add_task(task_fn::<(i32, i32), _, _>(
|(&a, &b): (&i32, &i32)| if a > b { a } else { b },
))
.depends_on((&shuffled[idx], &shuffled[idx + 1])),
]
})
+66 -73
View File
@@ -11,10 +11,10 @@ async fn test_workflow_with_conditional_paths() -> DagResult<()> {
let dag = DagRunner::new();
// Input validation
let input = dag.add_task(task_fn(|_: ()| async { 42 }));
let input = dag.add_task(task_fn::<(), _, _>(|_: ()| 42));
let validate = dag
.add_task(task_fn(|x: i32| async move {
.add_task(task_fn::<i32, _, _>(|&x: &i32| {
if x > 0 && x < 100 {
Ok(x)
} else {
@@ -25,37 +25,37 @@ async fn test_workflow_with_conditional_paths() -> DagResult<()> {
// Process valid input
let process = dag
.add_task(task_fn(|result: Result<i32, &str>| async move {
match result {
Ok(x) => x * 2,
.add_task(task_fn::<Result<_, _>, _, _>(
|result: &Result<i32, &str>| match result {
Ok(x) => *x * 2,
Err(_) => -1,
}
}))
},
))
.depends_on(validate);
// Parallel enhancement steps
let enhance1 = dag
.add_task(task_fn(|x: i32| async move { x + 10 }))
.add_task(task_fn::<i32, _, _>(|&x: &i32| x + 10))
.depends_on(process);
let enhance2 = dag
.add_task(task_fn(|x: i32| async move { x * 3 }))
.add_task(task_fn::<i32, _, _>(|&x: &i32| x * 3))
.depends_on(process);
let enhance3 = dag
.add_task(task_fn(|x: i32| async move { x - 5 }))
.add_task(task_fn::<i32, _, _>(|&x: &i32| x - 5))
.depends_on(process);
// Combine enhancements
let combine = dag
.add_task(task_fn(|(e1, e2, e3): (i32, i32, i32)| async move {
vec![e1, e2, e3]
}))
.add_task(task_fn::<(i32, i32, i32), _, _>(
|(&e1, &e2, &e3): (&i32, &i32, &i32)| vec![e1, e2, e3],
))
.depends_on((&enhance1, &enhance2, &enhance3));
// Final aggregation
let final_result = dag
.add_task(task_fn(|values: Vec<i32>| async move {
.add_task(task_fn::<Vec<_>, _, _>(|values: &Vec<i32>| {
values.iter().sum::<i32>()
}))
.depends_on(combine);
@@ -76,7 +76,7 @@ async fn test_map_reduce_pattern() -> DagResult<()> {
// Map phase: process 16 inputs in parallel
let mappers: Vec<dagx::TaskHandle<Vec<(&str, usize)>>> = (0..16)
.map(|i| {
let task = dag.add_task(task_fn(move |_: ()| async move {
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| {
// Simulate word count
vec![("word1", i % 3), ("word2", i % 5), ("word3", i % 7)]
}));
@@ -94,14 +94,23 @@ async fn test_map_reduce_pattern() -> DagResult<()> {
match deps.len() {
4 => dag
.add_task(task_fn(
.add_task(task_fn::<
(
Vec<(&str, usize)>,
Vec<(&str, usize)>,
Vec<(&str, usize)>,
Vec<(&str, usize)>,
),
_,
_,
>(
move |inputs: (
Vec<(&str, usize)>,
Vec<(&str, usize)>,
Vec<(&str, usize)>,
Vec<(&str, usize)>,
)| async move {
let mut combined = Vec::new();
&Vec<(&str, usize)>,
&Vec<(&str, usize)>,
&Vec<(&str, usize)>,
&Vec<(&str, usize)>,
)| {
let mut combined = Vec::<(&str, usize)>::new();
combined.extend(inputs.0);
combined.extend(inputs.1);
combined.extend(inputs.2);
@@ -119,11 +128,11 @@ async fn test_map_reduce_pattern() -> DagResult<()> {
let reducers: Vec<_> = shuffled
.iter()
.map(|shuffled_data| {
dag.add_task(task_fn(|data: Vec<(&str, usize)>| async move {
dag.add_task(task_fn::<Vec<_>, _, _>(|data: &Vec<(&str, usize)>| {
// Sum values by key
let mut totals = std::collections::HashMap::new();
for (key, value) in data {
*totals.entry(key).or_insert(0) += value;
*totals.entry(*key).or_insert(0) += value;
}
totals.len()
}))
@@ -133,8 +142,8 @@ async fn test_map_reduce_pattern() -> DagResult<()> {
// Final aggregation
let final_task = dag
.add_task(task_fn(
|(r1, r2, r3, r4): (usize, usize, usize, usize)| async move { r1 + r2 + r3 + r4 },
.add_task(task_fn::<(_, _, _, _), _, _>(
|(r1, r2, r3, r4): (&usize, &usize, &usize, &usize)| r1 + r2 + r3 + r4,
))
.depends_on((&reducers[0], &reducers[1], &reducers[2], &reducers[3]));
@@ -152,36 +161,30 @@ async fn test_pipeline_with_feedback() -> DagResult<()> {
let iteration_count = Arc::new(AtomicUsize::new(0));
// Initial value
let init = dag.add_task(task_fn(|_: ()| async { 1 }));
let init = dag.add_task(task_fn::<(), _, _>(|_: ()| 1));
// Stage 1: Transform
let stage1 = dag
.add_task(task_fn({
.add_task(task_fn::<i32, _, _>({
let counter = iteration_count.clone();
move |x: i32| {
move |x: &i32| {
let counter = counter.clone();
async move {
counter.fetch_add(1, Ordering::SeqCst);
x * 2
}
counter.fetch_add(1, Ordering::SeqCst);
x * 2
}
}))
.depends_on(init);
// Stage 2: Filter
let stage2 = dag
.add_task(task_fn(|x: i32| async move {
if x < 100 {
Some(x)
} else {
None
}
}))
.add_task(task_fn::<i32, _, _>(
|&x: &i32| if x < 100 { Some(x) } else { None },
))
.depends_on(stage1);
// Stage 3: Accumulate
let stage3 = dag
.add_task(task_fn(|opt: Option<i32>| async move {
.add_task(task_fn::<Option<_>, _, _>(|opt: &Option<i32>| {
opt.map(|x| x + 10).unwrap_or(0)
}))
.depends_on(stage2);
@@ -189,7 +192,7 @@ async fn test_pipeline_with_feedback() -> DagResult<()> {
// Note: Can't create actual cycles in DAG, but we simulate feedback
// by having a separate "feedback" task that would feed back in a real system
let _feedback = dag
.add_task(task_fn(|x: i32| async move {
.add_task(task_fn::<i32, _, _>(|&x: &i32| {
// In a real feedback loop, this would feed back to stage1
x / 2
}))
@@ -210,7 +213,7 @@ async fn test_scatter_gather_pattern() -> DagResult<()> {
// Scatter: distribute work to multiple workers
let source: TaskHandle<_> = dag
.add_task(task_fn(|_: ()| async {
.add_task(task_fn::<(), _, _>(|_: ()| {
vec![10, 20, 30, 40, 50, 60, 70, 80]
}))
.into();
@@ -218,7 +221,7 @@ async fn test_scatter_gather_pattern() -> DagResult<()> {
// Workers process chunks
let workers: Vec<_> = (0..4)
.map(|worker_id| {
dag.add_task(task_fn(move |data: Vec<i32>| async move {
dag.add_task(task_fn::<Vec<_>, _, _>(move |data: &Vec<i32>| {
// Each worker processes a chunk
let chunk_size = data.len() / 4;
let start = worker_id * chunk_size;
@@ -236,8 +239,8 @@ async fn test_scatter_gather_pattern() -> DagResult<()> {
// Gather: collect results from all workers
let gather = dag
.add_task(task_fn(
|(w0, w1, w2, w3): (i32, i32, i32, i32)| async move { w0 + w1 + w2 + w3 },
.add_task(task_fn::<(i32, i32, i32, i32), _, _>(
|(w0, w1, w2, w3): (&i32, &i32, &i32, &i32)| w0 + w1 + w2 + w3,
))
.depends_on((&workers[0], &workers[1], &workers[2], &workers[3]));
@@ -255,14 +258,12 @@ async fn test_fork_join_with_barriers() -> DagResult<()> {
let phase_counter = Arc::new(AtomicUsize::new(0));
// Fork phase
let parent = dag.add_task(task_fn({
let parent = dag.add_task(task_fn::<(), _, _>({
let counter = phase_counter.clone();
move |_: ()| {
let counter = counter.clone();
async move {
counter.store(1, Ordering::SeqCst);
100
}
counter.store(1, Ordering::SeqCst);
100
}
}));
@@ -273,12 +274,10 @@ async fn test_fork_join_with_barriers() -> DagResult<()> {
for i in 0..3 {
let counter = phase_counter.clone();
let task = dag
.add_task(task_fn(move |x: i32| {
.add_task(task_fn::<i32, _, _>(move |&x: &i32| {
let counter = counter.clone();
async move {
assert_eq!(counter.load(Ordering::SeqCst), 1);
x + i
}
assert_eq!(counter.load(Ordering::SeqCst), 1);
x + i
}))
.depends_on(prev1);
path1.push(task);
@@ -290,12 +289,10 @@ async fn test_fork_join_with_barriers() -> DagResult<()> {
for i in 0..3 {
let counter = phase_counter.clone();
let task = dag
.add_task(task_fn(move |x: i32| {
.add_task(task_fn::<i32, _, _>(move |&x: &i32| {
let counter = counter.clone();
async move {
assert_eq!(counter.load(Ordering::SeqCst), 1);
x * 2 + i
}
assert_eq!(counter.load(Ordering::SeqCst), 1);
x * 2 + i
}))
.depends_on(prev2);
path2.push(task);
@@ -304,28 +301,24 @@ async fn test_fork_join_with_barriers() -> DagResult<()> {
// Barrier: wait for all paths
let barrier = dag
.add_task(task_fn({
.add_task(task_fn::<(i32, i32), _, _>({
let counter = phase_counter.clone();
move |(p1, p2): (i32, i32)| {
move |(p1, p2): (&i32, &i32)| {
let counter = counter.clone();
async move {
counter.store(2, Ordering::SeqCst);
p1 + p2
}
counter.store(2, Ordering::SeqCst);
p1 + p2
}
}))
.depends_on((&path1[2], &path2[2]));
// Join phase
let join = dag
.add_task(task_fn({
.add_task(task_fn::<i32, _, _>({
let counter = phase_counter.clone();
move |x: i32| {
move |&x: &i32| {
let counter = counter.clone();
async move {
assert_eq!(counter.load(Ordering::SeqCst), 2);
x
}
assert_eq!(counter.load(Ordering::SeqCst), 2);
x
}
}))
.depends_on(barrier);
+21 -19
View File
@@ -14,10 +14,10 @@ async fn test_2d_grid_pattern() -> DagResult<()> {
// Initialize first row and column
#[allow(clippy::needless_range_loop)]
for i in 0..4 {
let task = dag.add_task(task_fn(move |_: ()| async move { i as i32 }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| i as i32));
grid[0][i] = Some(task.into());
if i > 0 {
let task = dag.add_task(task_fn(move |_: ()| async move { i as i32 * 10 }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| i as i32 * 10));
grid[i][0] = Some(task.into());
}
}
@@ -29,7 +29,9 @@ async fn test_2d_grid_pattern() -> DagResult<()> {
let left = grid[i][j - 1].as_ref().unwrap();
let task = dag
.add_task(task_fn(move |(a, l): (i32, i32)| async move { a + l }))
.add_task(task_fn::<(i32, i32), _, _>(move |(a, l): (&i32, &i32)| {
a + l
}))
.depends_on((above, left));
grid[i][j] = Some(task);
}
@@ -54,7 +56,7 @@ async fn test_3d_grid_pattern() -> DagResult<()> {
vec![vec![vec![None; size]; size]; size];
// Initialize origin
let origin = dag.add_task(task_fn(|_: ()| async { 1 }));
let origin = dag.add_task(task_fn::<(), _, _>(|_: ()| 1));
grid[0][0][0] = Some(origin.into());
// Fill the 3D grid
@@ -76,18 +78,20 @@ async fn test_3d_grid_pattern() -> DagResult<()> {
let task_handle: dagx::TaskHandle<usize> = match deps.len() {
0 => {
let t = dag.add_task(task_fn(move |_: ()| async move { x + y + z }));
let t = dag.add_task(task_fn::<(), _, _>(move |_: ()| x + y + z));
t.into()
}
1 => dag
.add_task(task_fn(move |prev: usize| async move { prev + 1 }))
.add_task(task_fn::<usize, _, _>(move |prev: &usize| prev + 1))
.depends_on(deps[0]),
2 => dag
.add_task(task_fn(move |(a, b): (usize, usize)| async move { a + b }))
.add_task(task_fn::<(usize, usize), _, _>(
move |(a, b): (&usize, &usize)| a + b,
))
.depends_on((&deps[0], &deps[1])),
3 => dag
.add_task(task_fn(
move |(a, b, c): (usize, usize, usize)| async move { a + b + c },
.add_task(task_fn::<(usize, usize, usize), _, _>(
move |(a, b, c): (&usize, &usize, &usize)| a + b + c,
))
.depends_on((&deps[0], &deps[1], &deps[2])),
_ => unreachable!(),
@@ -120,7 +124,7 @@ async fn test_hexagonal_grid() -> DagResult<()> {
let mut hex_grid = std::collections::HashMap::new();
// Center hex
let center_builder = dag.add_task(task_fn(|_: ()| async { 100 }));
let center_builder = dag.add_task(task_fn::<(), _, _>(|_: ()| 100));
let center: dagx::TaskHandle<i32> = center_builder.into();
hex_grid.insert((0, 0), center);
@@ -129,9 +133,7 @@ async fn test_hexagonal_grid() -> DagResult<()> {
for (i, &(dq, dr)) in directions.iter().enumerate() {
let neighbor: dagx::TaskHandle<i32> = dag
.add_task(task_fn(
move |c: i32| async move { c + (i as i32 + 1) * 10 },
))
.add_task(task_fn::<i32, _, _>(move |c: &i32| c + (i as i32 + 1) * 10))
.depends_on(center);
hex_grid.insert((dq, dr), neighbor);
}
@@ -159,15 +161,15 @@ async fn test_hexagonal_grid() -> DagResult<()> {
.collect();
let task: dagx::TaskHandle<i32> = if neighbors.len() == 2 {
dag.add_task(task_fn(move |(a, b): (i32, i32)| async move {
dag.add_task(task_fn::<(i32, i32), _, _>(move |(a, b): (&i32, &i32)| {
(a + b) / 2 + q + r
}))
.depends_on((&neighbors[0], &neighbors[1]))
} else if neighbors.len() == 1 {
dag.add_task(task_fn(move |n: i32| async move { n + q + r }))
dag.add_task(task_fn::<i32, _, _>(move |n: &i32| n + q + r))
.depends_on(neighbors[0])
} else {
let t = dag.add_task(task_fn(move |_: ()| async move { q + r }));
let t = dag.add_task(task_fn::<(), _, _>(move |_: ()| q + r));
t.into()
};
@@ -193,7 +195,7 @@ async fn test_toroidal_grid() -> DagResult<()> {
#[allow(clippy::needless_range_loop)]
for i in 0..SIZE {
for j in 0..SIZE {
let task = dag.add_task(task_fn(move |_: ()| async move { (i * SIZE + j) as i32 }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| (i * SIZE + j) as i32));
grid[i][j] = Some(task.into());
}
}
@@ -211,8 +213,8 @@ async fn test_toroidal_grid() -> DagResult<()> {
let right = grid[i][(j + 1) % SIZE].as_ref().unwrap();
let task = dag
.add_task(task_fn(
move |(c, u, d, l, r): (i32, i32, i32, i32, i32)| async move {
.add_task(task_fn::<(_, _, _, _, _), _, _>(
move |(c, u, d, l, r): (&i32, &i32, &i32, &i32, &i32)| {
// Average of self and 4 neighbors
(c + u + d + l + r) / 5
},
+36 -36
View File
@@ -10,7 +10,7 @@ async fn test_binary_tree_reduction() -> DagResult<()> {
// Create 8 leaf nodes
let leaves: Vec<_> = (0..8)
.map(|i| dag.add_task(task_fn(move |_: ()| async move { 1 << i })))
.map(|i| dag.add_task(task_fn::<(), _, _>(move |_: ()| 1 << i)))
.collect();
// Build binary tree reduction
@@ -23,7 +23,7 @@ async fn test_binary_tree_reduction() -> DagResult<()> {
for chunk in current_level.chunks(2) {
if chunk.len() == 2 {
let task = dag
.add_task(task_fn(|(a, b): (i32, i32)| async move { a + b }))
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a + b))
.depends_on((&chunk[0], &chunk[1]));
next_level.push(task);
} else {
@@ -51,7 +51,7 @@ async fn test_n_ary_tree() -> DagResult<()> {
// Build a 3-ary tree (each node has 3 children)
fn build_tree(dag: &DagRunner, depth: usize, value: i32) -> dagx::TaskHandle<i32> {
if depth == 0 {
let task = dag.add_task(task_fn(move |_: ()| async move { value }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| value));
return task.into();
}
@@ -59,9 +59,9 @@ async fn test_n_ary_tree() -> DagResult<()> {
.map(|i| build_tree(dag, depth - 1, value * 3 + i))
.collect();
dag.add_task(task_fn(move |(a, b, c): (i32, i32, i32)| async move {
value + a + b + c
}))
dag.add_task(task_fn::<(i32, i32, i32), _, _>(
move |(a, b, c): (&i32, &i32, &i32)| value + a + b + c,
))
.depends_on((&children[0], &children[1], &children[2]))
}
@@ -88,30 +88,30 @@ async fn test_unbalanced_tree() -> DagResult<()> {
// / \
// f g
let f: TaskHandle<_> = dag.add_task(task_fn(|_: ()| async { 1 })).into();
let g = dag.add_task(task_fn(|_: ()| async { 2 }));
let f: TaskHandle<_> = dag.add_task(task_fn::<(), _, _>(|_: ()| 1)).into();
let g = dag.add_task(task_fn::<(), _, _>(|_: ()| 2));
let c = dag
.add_task(task_fn(|x: i32| async move { x * 2 }))
.add_task(task_fn::<i32, _, _>(|&x: &i32| x * 2))
.depends_on(f);
let d_builder = dag.add_task(task_fn(|_: ()| async { 3 }));
let d_builder = dag.add_task(task_fn::<(), _, _>(|_: ()| 3));
let d: dagx::TaskHandle<i32> = d_builder.into();
let e = dag
.add_task(task_fn(|x: i32| async move { x * 3 }))
.add_task(task_fn::<i32, _, _>(|&x: &i32| x * 3))
.depends_on(g);
let a = dag
.add_task(task_fn(|(c, d): (i32, i32)| async move { c + d }))
.add_task(task_fn::<(i32, i32), _, _>(|(c, d): (&i32, &i32)| c + d))
.depends_on((&c, &d));
let b = dag
.add_task(task_fn(|e: i32| async move { e + 10 }))
.add_task(task_fn::<i32, _, _>(|e: &i32| e + 10))
.depends_on(e);
let root = dag
.add_task(task_fn(|(a, b): (i32, i32)| async move { a * b }))
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a * b))
.depends_on((&a, &b));
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
@@ -131,37 +131,39 @@ async fn test_trie_like_structure() -> DagResult<()> {
// Build a trie-like structure for paths
let root: TaskHandle<_> = dag
.add_task(task_fn(|_: ()| async { "root".to_string() }))
.add_task(task_fn::<(), _, _>(|_: ()| "root".to_string()))
.into();
// First level
let usr = dag
.add_task(task_fn(|r: String| async move { format!("{}/usr", r) }))
.add_task(task_fn::<String, _, _>(|r: &String| format!("{}/usr", r)))
.depends_on(root);
let etc = dag
.add_task(task_fn(|r: String| async move { format!("{}/etc", r) }))
.add_task(task_fn::<String, _, _>(|r: &String| format!("{}/etc", r)))
.depends_on(root);
let var = dag
.add_task(task_fn(|r: String| async move { format!("{}/var", r) }))
.add_task(task_fn::<String, _, _>(|r: &String| format!("{}/var", r)))
.depends_on(root);
// Second level
let usr_bin = dag
.add_task(task_fn(|u: String| async move { format!("{}/bin", u) }))
.add_task(task_fn::<String, _, _>(|u: &String| format!("{}/bin", u)))
.depends_on(usr);
let usr_lib = dag
.add_task(task_fn(|u: String| async move { format!("{}/lib", u) }))
.add_task(task_fn::<String, _, _>(|u: &String| format!("{}/lib", u)))
.depends_on(usr);
let etc_config = dag
.add_task(task_fn(|e: String| async move { format!("{}/config", e) }))
.add_task(task_fn::<String, _, _>(|e: &String| {
format!("{}/config", e)
}))
.depends_on(etc);
let var_log = dag
.add_task(task_fn(|v: String| async move { format!("{}/log", v) }))
.add_task(task_fn::<String, _, _>(|v: &String| format!("{}/log", v)))
.depends_on(var);
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
@@ -189,7 +191,7 @@ async fn test_balanced_k_ary_tree() -> DagResult<()> {
node_id: usize,
) -> dagx::TaskHandle<usize> {
if depth == 0 {
let task = dag.add_task(task_fn(move |_: ()| async move { node_id }));
let task = dag.add_task(task_fn::<(), _, _>(move |_: ()| node_id));
return task.into();
}
@@ -199,20 +201,18 @@ async fn test_balanced_k_ary_tree() -> DagResult<()> {
match k {
2 => dag
.add_task(task_fn(move |(a, b): (usize, usize)| async move {
node_id + a + b
}))
.add_task(task_fn::<(usize, usize), _, _>(
move |(a, b): (&usize, &usize)| node_id + a + b,
))
.depends_on((&children[0], &children[1])),
3 => dag
.add_task(task_fn(
move |(a, b, c): (usize, usize, usize)| async move { node_id + a + b + c },
.add_task(task_fn::<(usize, usize, usize), _, _>(
move |(a, b, c): (&usize, &usize, &usize)| node_id + a + b + c,
))
.depends_on((&children[0], &children[1], &children[2])),
4 => dag
.add_task(task_fn(
move |(a, b, c, d): (usize, usize, usize, usize)| async move {
node_id + a + b + c + d
},
.add_task(task_fn::<(usize, usize, usize, usize), _, _>(
move |(a, b, c, d): (&usize, &usize, &usize, &usize)| node_id + a + b + c + d,
))
.depends_on((&children[0], &children[1], &children[2], &children[3])),
_ => panic!("Unsupported k value"),
@@ -236,7 +236,7 @@ async fn test_merkle_tree_pattern() -> DagResult<()> {
// Simulate a Merkle tree for 8 data blocks
let data_blocks: Vec<_> = (0..8)
.map(|i| {
dag.add_task(task_fn(move |_: ()| async move {
dag.add_task(task_fn::<(), _, _>(move |_: ()| {
// Simulate hash of data block
format!("hash_{}", i)
}))
@@ -253,9 +253,9 @@ async fn test_merkle_tree_pattern() -> DagResult<()> {
for pair in current_level.chunks(2) {
if pair.len() == 2 {
let hash_task = dag
.add_task(task_fn(|(left, right): (String, String)| async move {
format!("hash({}_{})", left, right)
}))
.add_task(task_fn::<(String, String), _, _>(
|(left, right): (&String, &String)| format!("hash({}_{})", left, right),
))
.depends_on((&pair[0], &pair[1]));
next_level.push(hash_task);
} else {