1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! `bb::Aggregator` — Contract trait for federated aggregators.
//!
//! Each method takes a [`CompletionHandle`] AND returns
//! [`ContractResponse`]. See [`crate::contracts::index`] for the
//! sync (Now) vs async (Later) semantics.
//!
//! ## Shape
//!
//! Aggregation is a two-op cycle: `contribute(...)` writes one
//! peer's update into an in-progress buffer; `aggregate(...)`
//! reduces the buffer into the current aggregate AND returns it.
//! There is no separate `current_tensor()` op — `aggregate` is the
//! one-stop "compute + emit" call.
//!
//! ## Metadata channel
//!
//! Both `contribute` and `aggregate` carry a **typed** metadata
//! payload alongside the tensor, defined by the impl as the
//! associated type [`Aggregator::Metadata`].
//!
//! The metadata is transported through the slot table as a typed
//! Rust value — the framework's slot-value layer (`bb_ir::slot_value`)
//! holds every value as `Box<dyn SlotValue>` and downcasts to the
//! concrete type via `Any::downcast_ref`. Bincode/serde fires only
//! at the wire boundary (`SlotValue::to_wire_bytes`) and at
//! snapshot time. In-process contribute/aggregate calls see the
//! typed value directly — no serde overhead.
//!
//! This is the channel hierarchical aggregation needs: a child
//! `FedAvg` aggregator's `aggregate(...)` emits
//! `(params, FedAvgMeta { num_samples })`; the parent layer's
//! `contribute(...)` receives that and the `num_samples` weights
//! the child's contribution in the parent reduction. Both halves
//! work with the typed `FedAvgMeta` — only the wire crossing does
//! serde.
//!
//! Impls that have no metadata channel set `type Metadata = ();`.
use crate;
use crateRuntimeResourceRef;
use PeerId;
/// User-facing Contract trait for a federated/decentralized
/// aggregator. The derive bridges these methods to the engine's
/// [`crate::roles::AggregatorRuntime`] trait.