hyperactor_mesh/
lib.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9//! This crate provides hyperactor's mesh abstractions.
10
11#![feature(assert_matches)]
12#![feature(exit_status_error)]
13#![feature(impl_trait_in_bindings)]
14#![feature(get_disjoint_mut_helpers)]
15#![feature(exact_size_is_empty)]
16#![feature(async_fn_track_caller)]
17
18pub mod actor_mesh;
19pub mod alloc;
20mod assign;
21pub mod bootstrap;
22pub mod comm;
23pub mod config;
24pub mod connect;
25pub mod logging;
26pub mod mesh;
27pub mod mesh_selection;
28mod metrics;
29pub mod proc_mesh;
30pub mod reference;
31pub mod resource;
32pub mod router;
33pub mod shared_cell;
34pub mod shortuuid;
35pub mod supervision;
36#[cfg(target_os = "linux")]
37mod systemd;
38pub mod test_utils;
39mod testresource;
40pub mod v1;
41
42pub use actor_mesh::RootActorMesh;
43pub use actor_mesh::SlicedActorMesh;
44pub use bootstrap::Bootstrap;
45pub use bootstrap::bootstrap;
46pub use bootstrap::bootstrap_or_die;
47pub use comm::CommActor;
48pub use dashmap;
49pub use hyperactor_mesh_macros::sel;
50pub use mesh::Mesh;
51pub use ndslice::extent;
52pub use ndslice::sel_from_shape;
53pub use ndslice::selection;
54pub use ndslice::shape;
55pub use proc_mesh::ProcMesh;
56pub use proc_mesh::SlicedProcMesh;
57
58#[cfg(test)]
59mod tests {
60
61    #[test]
62    fn basic() {
63        use ndslice::selection::dsl;
64        use ndslice::selection::structurally_equal;
65
66        let actual = sel!(*, 0:4, *);
67        let expected = dsl::all(dsl::range(
68            ndslice::shape::Range(0, Some(4), 1),
69            dsl::all(dsl::true_()),
70        ));
71        assert!(structurally_equal(&actual, &expected));
72    }
73
74    #[cfg(FALSE)]
75    #[test]
76    fn shouldnt_compile() {
77        let _ = sel!(foobar);
78    }
79    // error: sel! parse failed: unexpected token: Ident { sym: foobar, span: #0 bytes(605..611) }
80    //   --> fbcode/monarch/hyperactor_mesh_macros/tests/basic.rs:19:13
81    //    |
82    // 19 |     let _ = sel!(foobar);
83    //    |             ^^^^^^^^^^^^ in this macro invocation
84    //   --> fbcode/monarch/hyperactor_mesh_macros/src/lib.rs:12:1
85    //    |
86    //    = note: in this expansion of `sel!`
87
88    use hyperactor_mesh_macros::sel;
89    use ndslice::assert_round_trip;
90    use ndslice::assert_structurally_eq;
91    use ndslice::selection::Selection;
92
93    macro_rules! assert_round_trip_match {
94        ($left:expr, $right:expr) => {{
95            assert_structurally_eq!($left, $right);
96            assert_round_trip!($left);
97            assert_round_trip!($right);
98        }};
99    }
100
101    #[test]
102    fn token_parser() {
103        use ndslice::selection::dsl::*;
104        use ndslice::shape;
105
106        assert_round_trip_match!(all(true_()), sel!(*));
107        assert_round_trip_match!(range(3, true_()), sel!(3));
108        assert_round_trip_match!(range(1..4, true_()), sel!(1:4));
109        assert_round_trip_match!(all(range(1..4, true_())), sel!(*, 1:4));
110        assert_round_trip_match!(range(shape::Range(0, None, 1), true_()), sel!(:));
111        assert_round_trip_match!(any(true_()), sel!(?));
112        assert_round_trip_match!(any(range(1..4, all(true_()))), sel!(?, 1:4, *));
113        assert_round_trip_match!(union(range(0, true_()), range(1, true_())), sel!(0 | 1));
114        assert_round_trip_match!(
115            intersection(range(0..4, true_()), range(2..6, true_())),
116            sel!(0:4 & 2:6)
117        );
118        assert_round_trip_match!(range(shape::Range(0, None, 1), true_()), sel!(:));
119        assert_round_trip_match!(all(true_()), sel!(*));
120        assert_round_trip_match!(any(true_()), sel!(?));
121        assert_round_trip_match!(all(all(all(true_()))), sel!(*, *, *));
122        assert_round_trip_match!(intersection(all(true_()), all(true_())), sel!(* & *));
123        assert_round_trip_match!(
124            all(all(union(
125                range(0..2, true_()),
126                range(shape::Range(6, None, 1), true_())
127            ))),
128            sel!(*, *, (:2|6:))
129        );
130        assert_round_trip_match!(
131            all(all(range(shape::Range(1, None, 2), true_()))),
132            sel!(*, *, 1::2)
133        );
134        assert_round_trip_match!(
135            range(
136                shape::Range(0, Some(1), 1),
137                any(range(shape::Range(0, Some(4), 1), true_()))
138            ),
139            sel!(0, ?, :4)
140        );
141        assert_round_trip_match!(range(shape::Range(1, Some(4), 2), true_()), sel!(1:4:2));
142        assert_round_trip_match!(range(shape::Range(0, None, 2), true_()), sel!(::2));
143        assert_round_trip_match!(
144            union(range(0..4, true_()), range(4..8, true_())),
145            sel!(0:4 | 4:8)
146        );
147        assert_round_trip_match!(
148            intersection(range(0..4, true_()), range(2..6, true_())),
149            sel!(0:4 & 2:6)
150        );
151        assert_round_trip_match!(
152            all(union(range(1..4, all(true_())), range(5..6, all(true_())))),
153            sel!(*, (1:4 | 5:6), *)
154        );
155        assert_round_trip_match!(
156            range(
157                0,
158                intersection(
159                    range(1..4, range(7, true_())),
160                    range(2..5, range(7, true_()))
161                )
162            ),
163            sel!(0, (1:4 & 2:5), 7)
164        );
165        assert_round_trip_match!(
166            all(all(union(
167                union(range(0..2, true_()), range(4..6, true_())),
168                range(shape::Range(6, None, 1), true_())
169            ))),
170            sel!(*, *, (:2 | 4:6 | 6:))
171        );
172        assert_round_trip_match!(intersection(all(true_()), all(true_())), sel!(* & *));
173        assert_round_trip_match!(union(all(true_()), all(true_())), sel!(* | *));
174        assert_round_trip_match!(
175            intersection(
176                range(0..2, true_()),
177                union(range(1, true_()), range(2, true_()))
178            ),
179            sel!(0:2 & (1 | 2))
180        );
181        assert_round_trip_match!(
182            all(all(intersection(
183                range(1..2, true_()),
184                range(2..3, true_())
185            ))),
186            sel!(*,*,(1:2&2:3))
187        );
188        assert_round_trip_match!(
189            intersection(all(all(all(true_()))), all(all(all(true_())))),
190            sel!((*,*,*) & (*,*,*))
191        );
192        assert_round_trip_match!(
193            intersection(
194                range(0, all(all(true_()))),
195                range(0, union(range(1, all(true_())), range(3, all(true_()))))
196            ),
197            sel!((0, *, *) & (0, (1 | 3), *))
198        );
199        assert_round_trip_match!(
200            intersection(
201                range(0, all(all(true_()))),
202                range(
203                    0,
204                    union(
205                        range(1, range(2..5, true_())),
206                        range(3, range(2..5, true_()))
207                    )
208                )
209            ),
210            sel!((0, *, *) & (0, (1 | 3), 2:5))
211        );
212        assert_round_trip_match!(all(true_()), sel!((*)));
213        assert_round_trip_match!(range(1..4, range(2, true_())), sel!(((1:4), 2)));
214        assert_round_trip_match!(sel!(1:4 & 5:6 | 7:8), sel!((1:4 & 5:6) | 7:8));
215        assert_round_trip_match!(
216            union(
217                intersection(all(all(true_())), all(all(true_()))),
218                all(all(true_()))
219            ),
220            sel!((*,*) & (*,*) | (*,*))
221        );
222        assert_round_trip_match!(all(true_()), sel!(*));
223        assert_round_trip_match!(sel!(((1:4))), sel!(1:4));
224        assert_round_trip_match!(sel!(*, (*)), sel!(*, *));
225        assert_round_trip_match!(
226            intersection(
227                range(0, range(1..4, true_())),
228                range(0, union(range(2, all(true_())), range(3, all(true_()))))
229            ),
230            sel!((0,1:4)&(0,(2|3),*))
231        );
232
233        //assert_round_trip_match!(true_(), sel!(foo)); // sel! macro: parse error: Parsing Error: Error { input: "foo", code: Tag }
234
235        assert_round_trip_match!(
236            sel!(0 & (0, (1|3), *)),
237            intersection(
238                range(0, true_()),
239                range(0, union(range(1, all(true_())), range(3, all(true_()))))
240            )
241        );
242        assert_round_trip_match!(
243            sel!(0 & (0, (3|1), *)),
244            intersection(
245                range(0, true_()),
246                range(0, union(range(3, all(true_())), range(1, all(true_()))))
247            )
248        );
249        assert_round_trip_match!(
250            sel!((*, *, *) & (*, *, (2 | 4))),
251            intersection(
252                all(all(all(true_()))),
253                all(all(union(range(2, true_()), range(4, true_()))))
254            )
255        );
256        assert_round_trip_match!(
257            sel!((*, *, *) & (*, *, (4 | 2))),
258            intersection(
259                all(all(all(true_()))),
260                all(all(union(range(4, true_()), range(2, true_()))))
261            )
262        );
263        assert_round_trip_match!(
264            sel!((*, (1|2)) & (*, (2|1))),
265            intersection(
266                all(union(range(1, true_()), range(2, true_()))),
267                all(union(range(2, true_()), range(1, true_())))
268            )
269        );
270        assert_round_trip_match!(
271            sel!((*, *, *) & *),
272            intersection(all(all(all(true_()))), all(true_()))
273        );
274        assert_round_trip_match!(
275            sel!(* & (*, *, *)),
276            intersection(all(true_()), all(all(all(true_()))))
277        );
278
279        assert_round_trip_match!(
280            sel!( (*, *, *) & ((*, *, *) & (*, *, *)) ),
281            intersection(
282                all(all(all(true_()))),
283                intersection(all(all(all(true_()))), all(all(all(true_()))))
284            )
285        );
286        assert_round_trip_match!(
287            sel!((1, *, *) | (0 & (0, 3, *))),
288            union(
289                range(1, all(all(true_()))),
290                intersection(range(0, true_()), range(0, range(3, all(true_()))))
291            )
292        );
293        assert_round_trip_match!(
294            sel!(((0, *)| (1, *)) & ((1, *) | (0, *))),
295            intersection(
296                union(range(0, all(true_())), range(1, all(true_()))),
297                union(range(1, all(true_())), range(0, all(true_())))
298            )
299        );
300        assert_round_trip_match!(sel!(*, 8:8), all(range(8..8, true_())));
301        assert_round_trip_match!(
302            sel!((*, 1) & (*, 8 : 8)),
303            intersection(all(range(1..2, true_())), all(range(8..8, true_())))
304        );
305        assert_round_trip_match!(
306            sel!((*, 8 : 8) | (*, 1)),
307            union(all(range(8..8, true_())), all(range(1..2, true_())))
308        );
309        assert_round_trip_match!(
310            sel!((*, 1) | (*, 2:8)),
311            union(all(range(1..2, true_())), all(range(2..8, true_())))
312        );
313        assert_round_trip_match!(
314            sel!((*, *, *) & (*, *, 2:8)),
315            intersection(all(all(all(true_()))), all(all(range(2..8, true_()))))
316        );
317    }
318}