1use eredu_checkpoint::{
4 recipe::DerivedWeightRecipe,
5 store::{CheckpointLease, CheckpointSource},
6};
7use eredu_core::{BoundedCompletion, Completion, Submission};
8use eredu_nn::NeuralBackend;
9
10use crate::CommunicationPeerCounts;
11
12pub trait SubmissionBackend: NeuralBackend {
14 type Executor: ?Sized;
16 type OwnedExecutor: std::borrow::Borrow<Self::Executor>;
18 type Completion: Completion;
20
21 fn fork_executors(
23 executor: &Self::Executor,
24 count: usize,
25 ) -> Result<Vec<Self::OwnedExecutor>, <Self::Completion as Completion>::Error>;
26
27 fn submit<'a, I>(
29 executor: &Self::Executor,
30 values: I,
31 ) -> Result<Self::Completion, <Self::Completion as Completion>::Error>
32 where
33 Self::Tensor: 'a,
34 I: IntoIterator<Item = &'a Self::Tensor>;
35
36 fn order_after(
38 completion: &Self::Completion,
39 executor: &Self::Executor,
40 ) -> Result<(), <Self::Completion as Completion>::Error>;
41
42 fn retain_until_complete<T: Send + 'static>(
44 executor: &Self::Executor,
45 completion: &Self::Completion,
46 value: T,
47 ) -> Result<(), <Self::Completion as Completion>::Error>;
48}
49
50pub trait ParameterBackend: NeuralBackend {
52 type Parameter: 'static;
54 type MaterializedWeight;
56 type MaterializationContext: ?Sized;
58 type Materialization;
60 type ParameterError: std::error::Error + Send + Sync + 'static;
62
63 fn preflight_recipe(
68 recipe: &DerivedWeightRecipe,
69 source: &dyn CheckpointSource,
70 ) -> Result<(), Self::ParameterError>;
71
72 fn materialize(
74 lease: CheckpointLease,
75 context: &Self::MaterializationContext,
76 ) -> Result<Self::Materialization, Self::ParameterError>;
77
78 fn materialize_recipe(
80 recipe: &DerivedWeightRecipe,
81 source: &dyn CheckpointSource,
82 context: &Self::MaterializationContext,
83 ) -> Result<Self::Materialization, Self::ParameterError>;
84
85 fn materialized_weight(materialization: &Self::Materialization) -> &Self::MaterializedWeight;
87
88 fn finish_materialization(
90 materialization: Self::Materialization,
91 ) -> Result<Self::MaterializedWeight, Self::ParameterError>;
92
93 fn share_materialized_weight(
96 weight: &Self::MaterializedWeight,
97 ) -> Result<Self::MaterializedWeight, Self::ParameterError>;
98
99 fn validate_bind(
101 parameter: &Self::Parameter,
102 weight: &Self::MaterializedWeight,
103 ) -> Result<(), Self::ParameterError>;
104
105 fn bind(parameter: &mut Self::Parameter, weight: Self::MaterializedWeight);
110}
111
112pub trait TransferBackend: SubmissionBackend + ParameterBackend {
114 type HostBuffer;
116 type Transfer: Completion<Error = Self::TransferError>;
118 type TransferError: std::error::Error + Send + Sync + 'static;
120
121 fn promote(
123 executor: &Self::Executor,
124 host: &Self::HostBuffer,
125 ) -> Result<(Self::MaterializedWeight, Self::Transfer), Self::TransferError>;
126
127 fn demote(
129 executor: &Self::Executor,
130 weight: &Self::MaterializedWeight,
131 ) -> Result<(Self::HostBuffer, Self::Transfer), Self::TransferError>;
132}
133
134pub trait CollectiveBackend: SubmissionBackend {
136 type Group: ?Sized;
138 type CollectiveError: std::error::Error + Send + Sync + 'static;
140
141 fn all_reduce(
143 value: Self::Tensor,
144 group: &Self::Group,
145 executor: &Self::Executor,
146 ) -> Result<Self::Tensor, Self::CollectiveError>;
147
148 fn all_gather(
150 value: Self::Tensor,
151 group: &Self::Group,
152 executor: &Self::Executor,
153 ) -> Result<Self::Tensor, Self::CollectiveError>;
154
155 fn all_to_all(
157 value: Self::Tensor,
158 group: &Self::Group,
159 executor: &Self::Executor,
160 ) -> Result<Self::Tensor, Self::CollectiveError>;
161}
162
163pub trait CommunicationBackend: SubmissionBackend {
168 type CommunicationGroup: ?Sized;
170 type CommunicationRoute: ?Sized;
172 type CommunicationCompletion: Completion<Error = Self::CommunicationError>
174 + BoundedCompletion<Error = Self::CommunicationError>;
175 type CommunicationError: std::error::Error + Send + Sync + 'static;
177
178 fn submit_local_dependencies<'a, I>(
186 values: I,
187 executor: &Self::Executor,
188 ) -> Result<Submission<(), Self::CommunicationCompletion>, Self::CommunicationError>
189 where
190 Self::Tensor: 'a,
191 I: IntoIterator<Item = &'a Self::Tensor>;
192}
193
194pub trait SumReductionBackend: CommunicationBackend {
196 fn all_reduce_sum(
198 value: Self::Tensor,
199 group: &Self::CommunicationGroup,
200 executor: &Self::Executor,
201 ) -> Result<Submission<Self::Tensor, Self::CommunicationCompletion>, Self::CommunicationError>;
202}
203
204pub trait EvenGatherBackend: CommunicationBackend {
206 fn all_gather_even(
208 value: Self::Tensor,
209 axis: usize,
210 group: &Self::CommunicationGroup,
211 executor: &Self::Executor,
212 ) -> Result<Submission<Self::Tensor, Self::CommunicationCompletion>, Self::CommunicationError>;
213}
214
215pub trait UnevenGatherBackend: CommunicationBackend {
217 fn all_gather_uneven(
219 value: Self::Tensor,
220 counts: &[usize],
221 axis: usize,
222 group: &Self::CommunicationGroup,
223 executor: &Self::Executor,
224 ) -> Result<Submission<Self::Tensor, Self::CommunicationCompletion>, Self::CommunicationError>;
225}
226
227pub trait VariableAllToAllBackend: CommunicationBackend {
229 fn variable_all_to_all(
231 value: Self::Tensor,
232 counts: &CommunicationPeerCounts,
233 axis: usize,
234 group: &Self::CommunicationGroup,
235 executor: &Self::Executor,
236 ) -> Result<Submission<Self::Tensor, Self::CommunicationCompletion>, Self::CommunicationError>;
237}
238
239pub trait PointToPointBackend: CommunicationBackend {
241 #[allow(
243 clippy::type_complexity,
244 reason = "the signature exposes the tensor bundle and exact completion without erasure"
245 )]
246 fn send_receive(
247 values: Vec<RoleExactBoundaryValue<Self::Tensor>>,
248 route: &Self::CommunicationRoute,
249 executor: &Self::Executor,
250 ) -> Result<
251 Submission<Vec<Self::Tensor>, Self::CommunicationCompletion>,
252 Self::CommunicationError,
253 >;
254}
255
256#[derive(Debug, Clone, Eq, PartialEq)]
265pub struct RoleExactBoundaryValue<T> {
266 header: Vec<u8>,
267 tensor: T,
268}
269
270impl<T> RoleExactBoundaryValue<T> {
271 pub(crate) fn new(header: Vec<u8>, tensor: T) -> Self {
272 Self { header, tensor }
273 }
274
275 pub fn header(&self) -> &[u8] {
277 &self.header
278 }
279
280 pub const fn tensor(&self) -> &T {
282 &self.tensor
283 }
284
285 pub fn into_parts(self) -> (Vec<u8>, T) {
287 (self.header, self.tensor)
288 }
289}
290
291pub trait BroadcastBackend: CommunicationBackend {
293 fn broadcast(
295 value: Self::Tensor,
296 root: usize,
297 group: &Self::CommunicationGroup,
298 executor: &Self::Executor,
299 ) -> Result<Submission<Self::Tensor, Self::CommunicationCompletion>, Self::CommunicationError>;
300}
301
302pub trait BarrierBackend: CommunicationBackend {
304 fn barrier(
306 group: &Self::CommunicationGroup,
307 executor: &Self::Executor,
308 ) -> Result<Self::CommunicationCompletion, Self::CommunicationError>;
309}
310
311pub trait FailureAgreementBackend: CommunicationBackend {
316 type FailureAgreementOutput;
319
320 fn agree_success(
322 local_success: bool,
323 group: &Self::CommunicationGroup,
324 executor: &Self::Executor,
325 ) -> Result<
326 Submission<Self::FailureAgreementOutput, Self::CommunicationCompletion>,
327 Self::CommunicationError,
328 >;
329
330 fn resolve_failure_agreement(
332 output: Self::FailureAgreementOutput,
333 ) -> Result<bool, Self::CommunicationError>;
334}