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