@@ -59,9 +59,10 @@ def __new__(cls, *args, **kwargs):
5959
6060 return object .__new__ (cls )
6161
62- def __init__ (self , * , python_type , name , shortname , bytes , is_weak ):
62+ def __init__ (self , * , python_type , name , shortname , bytes , is_weak , variant = None ):
6363 self ._python_type = python_type
6464 self ._name = name
65+ self ._variant = variant
6566 self ._shortname = shortname
6667 self ._bytes = bytes
6768 self ._is_weak = is_weak
@@ -80,23 +81,30 @@ def is_weak(self):
8081 return self ._is_weak
8182
8283 def shortname (self ):
83- return f"{ self ._shortname } { 8 * self ._bytes } "
84+ return f"{ self ._shortname } { 8 * self ._bytes } { f'_ { self . _variant } ' if self . _variant else '' } "
8485
8586 # TODO Fix name printing
8687 def __repr__ (self ):
87- return f"{ self ._name } { 8 * self ._bytes } { '_' if self ._is_weak else '' } "
88+ return (
89+ f"{ self ._name } { 8 * self ._bytes } { f'_{ self ._variant } ' if self ._variant else '' } { '_' if self ._is_weak else '' } "
90+ )
8891
8992 def __str__ (self ):
9093 return self .__repr__ ()
9194
9295 def __hash__ (self ) -> int :
93- return hash ((self ._name , self ._bytes , self ._is_weak ))
96+ return hash ((self ._name , self ._bytes , self ._is_weak , f" { self . _variant if self . _variant else '' } " ))
9497
9598 def __eq__ (self , other ) -> bool :
9699 if not isinstance (other , dtype ):
97100 return False
98101
99- return self ._name == other ._name and self ._bytes == other ._bytes and self ._is_weak == other ._is_weak
102+ return (
103+ self ._name == other ._name
104+ and self ._bytes == other ._bytes
105+ and self ._is_weak == other ._is_weak
106+ and self ._variant == other ._variant
107+ )
100108
101109
102110class exact (dtype ):
@@ -152,14 +160,24 @@ class inexact(dtype):
152160
153161
154162class floating (inexact ):
155- """Base class for the floating dtypes: bfloat16, float16, float32, float64."""
163+ """Base class for the floating dtypes: float8, bfloat16, float16, float32, float64."""
156164
157- def __init__ (self , name , shortname , * , bytes , is_weak ):
158- super ().__init__ (python_type = float , name = name , shortname = shortname , bytes = bytes , is_weak = is_weak )
165+ def __init__ (self , name , shortname , * , bytes , is_weak , variant = None ):
166+ super ().__init__ (
167+ python_type = float , name = name , shortname = shortname , bytes = bytes , is_weak = is_weak , variant = variant
168+ )
159169
160170
161171bfloat16 = floating ("bfloat" , "bf" , bytes = 2 , is_weak = False )
162172bfloat16_ = floating ("bfloat" , "bf" , bytes = 2 , is_weak = True )
173+ float8_e5m2 = floating ("float" , "f" , bytes = 1 , is_weak = False , variant = "e5m2" )
174+ float8_e5m2_ = floating ("float" , "f" , bytes = 1 , is_weak = True , variant = "e5m2" )
175+ float8_e5m2fnuz = floating ("float" , "f" , bytes = 1 , is_weak = False , variant = "e5m2fnuz" )
176+ float8_e5m2fnuz_ = floating ("float" , "f" , bytes = 1 , is_weak = True , variant = "e5m2fnuz" )
177+ float8_e4m3fn = floating ("float" , "f" , bytes = 1 , is_weak = False , variant = "e4m3fn" )
178+ float8_e4m3fn_ = floating ("float" , "f" , bytes = 1 , is_weak = True , variant = "e4m3fn" )
179+ float8_e4m3fnuz = floating ("float" , "f" , bytes = 1 , is_weak = False , variant = "e4m3fnuz" )
180+ float8_e4m3fnuz_ = floating ("float" , "f" , bytes = 1 , is_weak = True , variant = "e4m3fnuz" )
163181float16 = floating ("float" , "f" , bytes = 2 , is_weak = False )
164182float16_ = floating ("float" , "f" , bytes = 2 , is_weak = True )
165183float32 = floating ("float" , "f" , bytes = 4 , is_weak = False )
@@ -200,6 +218,14 @@ def __init__(self, name, shortname, *, bytes, is_weak):
200218 int64_ ,
201219 bfloat16 ,
202220 bfloat16_ ,
221+ float8_e5m2 ,
222+ float8_e5m2_ ,
223+ float8_e5m2fnuz ,
224+ float8_e5m2fnuz_ ,
225+ float8_e4m3fn ,
226+ float8_e4m3fn_ ,
227+ float8_e4m3fnuz ,
228+ float8_e4m3fnuz_ ,
203229 float16 ,
204230 float16_ ,
205231 float32 ,
@@ -242,6 +268,10 @@ def __init__(self, name, shortname, *, bytes, is_weak):
242268
243269float_dtypes = {d for d in all_dtypes if isinstance (d , floating )} | {float }
244270
271+ float_math_dtypes = {d for d in all_dtypes if isinstance (d , floating ) and d .bytes >= 2 }
272+
273+ float_8bit_dtypes = {d for d in all_dtypes if (isinstance (d , floating ) and d .bytes == 1 )}
274+
245275complex_dtypes = {d for d in all_dtypes if isinstance (d , complexfloating )} | {complex }
246276
247277inexact_dtypes = float_dtypes | complex_dtypes
@@ -306,11 +336,12 @@ def has_subdtype(x, cls):
306336
307337
308338# Translates a sequence of dtypes and dtype classes into a concrete set of corresponding (strong) dtypes
309- def resolve_dtypes (args ) :
339+ def resolve_dtypes (args : Iterable ) -> set [ dtype ] :
310340 dtypes = set ()
311341 for arg in args :
312342 if isinstance (arg , dtype ):
313- dtypes .add (arg )
343+ if not arg .is_weak :
344+ dtypes .add (arg )
314345 continue
315346
316347 if isinstance (arg , Iterable ):
@@ -320,7 +351,8 @@ def resolve_dtypes(args):
320351 lambda : f"Iterables passed to resolve_dtypes must only contain dtypes, but found an Iterable with { a } " ,
321352 exception_type = NotImplementedError ,
322353 )
323- dtypes .add (a )
354+ if not a .is_weak :
355+ dtypes .add (a )
324356
325357 baseutils .check (
326358 arg in (dtype , exact , signedinteger , unsignedinteger , bool_ , inexact , floating , complexfloating ),
@@ -373,6 +405,10 @@ def corresponding_complex_dtype(dtype):
373405 int32 : int32_ ,
374406 int64 : int64_ ,
375407 bfloat16 : bfloat16_ ,
408+ float8_e5m2 : float8_e5m2_ ,
409+ float8_e5m2fnuz : float8_e5m2fnuz_ ,
410+ float8_e4m3fn : float8_e4m3fn_ ,
411+ float8_e4m3fnuz : float8_e4m3fnuz_ ,
376412 float16 : float16_ ,
377413 float32 : float32_ ,
378414 float64 : float64_ ,
@@ -520,6 +556,14 @@ def are_same_dtypes(a, b, *, weak_and_strong_are_equivalent=True):
520556 int64 : torch .int64 ,
521557 bfloat16_ : torch .bfloat16 ,
522558 bfloat16 : torch .bfloat16 ,
559+ float8_e5m2 : torch .float8_e5m2 ,
560+ float8_e5m2_ : torch .float8_e5m2 ,
561+ float8_e5m2fnuz : torch .float8_e5m2fnuz ,
562+ float8_e5m2fnuz_ : torch .float8_e5m2fnuz ,
563+ float8_e4m3fn : torch .float8_e4m3fn ,
564+ float8_e4m3fn_ : torch .float8_e4m3fn ,
565+ float8_e4m3fnuz : torch .float8_e4m3fnuz ,
566+ float8_e4m3fnuz_ : torch .float8_e4m3fnuz ,
523567 float16_ : torch .float16 ,
524568 float16 : torch .float16 ,
525569 float32_ : torch .float32 ,
@@ -551,7 +595,7 @@ def to_torch_dtype(x: None | torch.dtype | dtype) -> None | torch.dtype:
551595
552596# Converts NumPy dtypes to and from thunder dtypes
553597
554- # NOTE NumPy does not support the bfloat16 or complexhalf (complex32) datatypes
598+ # NOTE NumPy does not support the bfloat16, complexhalf (complex32) or float8 datatypes
555599_thunder_to_numpy_dtype_map = {
556600 bool : np .bool_ ,
557601 int : np .int_ ,
0 commit comments