Skip to content

Commit 379679a

Browse files
thomasywangmeta-codesync[bot]
authored andcommitted
Create hyperactor_named crate
Summary: We need to make `hyperactor_named` it's own crate to break a circular dependency Differential Revision: D87941210
1 parent f974b26 commit 379679a

File tree

4 files changed

+240
-174
lines changed

4 files changed

+240
-174
lines changed

hyperactor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ futures = { version = "0.3.31", features = ["async-await", "compat"] }
5656
hostname = "0.3"
5757
humantime = "2.1"
5858
hyperactor_macros = { version = "0.0.0", path = "../hyperactor_macros" }
59+
hyperactor_named = { version = "0.0.0", path = "../hyperactor_named" }
5960
hyperactor_telemetry = { version = "0.0.0", path = "../hyperactor_telemetry" }
6061
indenter = "0.3.3"
6162
inventory = "0.3.21"

hyperactor/src/data.rs

Lines changed: 2 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,15 @@ use std::io::Cursor;
1616
use std::sync::LazyLock;
1717

1818
use enum_as_inner::EnumAsInner;
19+
pub use hyperactor_named::Named;
20+
pub use hyperactor_named::intern_typename;
1921
use serde::Deserialize;
2022
use serde::Serialize;
2123
use serde::de::DeserializeOwned;
2224

2325
use crate as hyperactor;
2426
use crate::config;
2527

26-
/// A [`Named`] type is a type that has a globally unique name.
27-
pub trait Named: Sized + 'static {
28-
/// The globally unique type name for the type.
29-
/// This should typically be the fully qualified Rust name of the type.
30-
fn typename() -> &'static str;
31-
32-
/// A globally unique hash for this type.
33-
/// TODO: actually enforce perfect hashing
34-
fn typehash() -> u64 {
35-
// The `Named` macro overrides this implementation with one that
36-
// memoizes the hash.
37-
cityhasher::hash(Self::typename())
38-
}
39-
40-
/// The TypeId for this type. TypeIds are unique only within a binary,
41-
/// and should not be used for global identification.
42-
fn typeid() -> TypeId {
43-
TypeId::of::<Self>()
44-
}
45-
46-
/// The globally unique port for this type. Typed ports are in the range
47-
/// of 1<<63..1<<64-1.
48-
fn port() -> u64 {
49-
Self::typehash() | (1 << 63)
50-
}
51-
52-
/// If the named type is an enum, this returns the name of the arm
53-
/// of the value self.
54-
fn arm(&self) -> Option<&'static str> {
55-
None
56-
}
57-
58-
/// An unsafe version of 'arm', accepting a pointer to the value,
59-
/// for use in type-erased settings.
60-
unsafe fn arm_unchecked(self_: *const ()) -> Option<&'static str> {
61-
// SAFETY: This isn't safe. We're passing it on.
62-
unsafe { &*(self_ as *const Self) }.arm()
63-
}
64-
}
65-
6628
#[doc(hidden)]
6729
/// Dump trait for Named types that are also serializable/deserializable.
6830
/// This is a utility used by [`Serialized::dump`], and is not intended
@@ -79,140 +41,6 @@ impl<T: Named + Serialize + for<'de> Deserialize<'de>> NamedDumpable for T {
7941
}
8042
}
8143

82-
macro_rules! impl_basic {
83-
($t:ty) => {
84-
impl Named for $t {
85-
fn typename() -> &'static str {
86-
stringify!($t)
87-
}
88-
}
89-
};
90-
}
91-
92-
impl_basic!(());
93-
impl_basic!(bool);
94-
impl_basic!(i8);
95-
impl_basic!(u8);
96-
impl_basic!(i16);
97-
impl_basic!(u16);
98-
impl_basic!(i32);
99-
impl_basic!(u32);
100-
impl_basic!(i64);
101-
impl_basic!(u64);
102-
impl_basic!(i128);
103-
impl_basic!(u128);
104-
impl_basic!(isize);
105-
impl_basic!(usize);
106-
impl_basic!(f32);
107-
impl_basic!(f64);
108-
impl_basic!(String);
109-
impl_basic!(std::net::IpAddr);
110-
impl_basic!(std::net::Ipv4Addr);
111-
impl_basic!(std::net::Ipv6Addr);
112-
impl_basic!(std::time::Duration);
113-
impl_basic!(std::time::SystemTime);
114-
impl_basic!(bytes::Bytes);
115-
// This is somewhat unfortunate. We should separate this module out into
116-
// its own crate, and just derive(Named) in `ndslice`. As it is, this would
117-
// create a circular (and heavy!) dependency for `ndslice`.
118-
impl_basic!(ndslice::Point);
119-
120-
impl Named for &'static str {
121-
fn typename() -> &'static str {
122-
"&str"
123-
}
124-
}
125-
126-
// A macro that implements type-keyed interning of typenames. This is useful
127-
// for implementing [`Named`] for generic types.
128-
#[doc(hidden)] // not part of the public API
129-
#[macro_export]
130-
macro_rules! intern_typename {
131-
($key:ty, $format_string:expr, $($args:ty),+) => {
132-
{
133-
static CACHE: std::sync::LazyLock<$crate::dashmap::DashMap<std::any::TypeId, &'static str>> =
134-
std::sync::LazyLock::new($crate::dashmap::DashMap::new);
135-
136-
match CACHE.entry(std::any::TypeId::of::<$key>()) {
137-
$crate::dashmap::mapref::entry::Entry::Vacant(entry) => {
138-
let typename = format!($format_string, $(<$args>::typename()),+).leak();
139-
entry.insert(typename);
140-
typename
141-
}
142-
$crate::dashmap::mapref::entry::Entry::Occupied(entry) => *entry.get(),
143-
}
144-
}
145-
};
146-
}
147-
pub use intern_typename;
148-
149-
macro_rules! tuple_format_string {
150-
($a:ident,) => { "{}" };
151-
($a:ident, $($rest_a:ident,)+) => { concat!("{}, ", tuple_format_string!($($rest_a,)+)) };
152-
}
153-
154-
macro_rules! impl_tuple_peel {
155-
($name:ident, $($other:ident,)*) => (impl_tuple! { $($other,)* })
156-
}
157-
158-
macro_rules! impl_tuple {
159-
() => ();
160-
( $($name:ident,)+ ) => (
161-
impl<$($name:Named + 'static),+> Named for ($($name,)+) {
162-
fn typename() -> &'static str {
163-
intern_typename!(Self, concat!("(", tuple_format_string!($($name,)+), ")"), $($name),+)
164-
}
165-
}
166-
impl_tuple_peel! { $($name,)+ }
167-
)
168-
}
169-
170-
impl_tuple! { E, D, C, B, A, Z, Y, X, W, V, U, T, }
171-
172-
impl<T: Named + 'static> Named for Option<T> {
173-
fn typename() -> &'static str {
174-
intern_typename!(Self, "Option<{}>", T)
175-
}
176-
}
177-
178-
impl<T: Named + 'static> Named for Vec<T> {
179-
fn typename() -> &'static str {
180-
intern_typename!(Self, "Vec<{}>", T)
181-
}
182-
}
183-
184-
impl<K: Named + 'static, V: Named + 'static> Named for HashMap<K, V> {
185-
fn typename() -> &'static str {
186-
intern_typename!(Self, "HashMap<{}, {}>", K, V)
187-
}
188-
}
189-
190-
impl<T: Named + 'static, E: Named + 'static> Named for Result<T, E> {
191-
fn typename() -> &'static str {
192-
intern_typename!(Self, "Result<{}, {}>", T, E)
193-
}
194-
}
195-
196-
impl<T: Named + 'static> Named for std::ops::Range<T> {
197-
fn typename() -> &'static str {
198-
intern_typename!(Self, "std::ops::Range<{}>", T)
199-
}
200-
}
201-
202-
static SHAPE_CACHED_TYPEHASH: LazyLock<u64> =
203-
LazyLock::new(|| cityhasher::hash(<ndslice::shape::Shape as Named>::typename()));
204-
205-
impl Named for ndslice::shape::Shape {
206-
fn typename() -> &'static str {
207-
"ndslice::shape::Shape"
208-
}
209-
210-
fn typehash() -> u64 {
211-
*SHAPE_CACHED_TYPEHASH
212-
}
213-
}
214-
215-
/// Really internal, but needs to be exposed for macro.
21644
#[doc(hidden)]
21745
#[derive(Debug)]
21846
pub struct TypeInfo {

hyperactor_named/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# @generated by autocargo from //monarch/hyperactor_named:hyperactor_named
2+
3+
[package]
4+
name = "hyperactor_named"
5+
version = "0.0.0"
6+
authors = ["Facebook <opensource+crates-hyperactor@fb.com>"]
7+
edition = "2021"
8+
description = "Core Named trait for Hyperactor types with globally unique names"
9+
repository = "https://github.com/meta-pytorch/monarch/"
10+
license = "BSD-3-Clause"
11+
12+
[lib]
13+
edition = "2024"
14+
15+
[dependencies]
16+
bytes = { version = "1.10", features = ["serde"] }
17+
cityhasher = "0.1.0"
18+
dashmap = { version = "5.5.3", features = ["rayon", "serde"] }
19+
ndslice = { version = "0.0.0", path = "../ndslice" }

0 commit comments

Comments
 (0)