#[non_exhaustive]pub enum DataType {
Show 32 variants
U8,
U16,
U32,
I8,
I16,
I32,
I64,
U64,
Vec2U32,
Vec4U32,
Bool,
Bytes,
Array {
element_size: usize,
},
F16,
BF16,
F32,
F64,
Tensor,
Handle(TypeId),
Vec {
element: Box<DataType>,
count: u8,
},
TensorShaped {
element: Box<DataType>,
shape: SmallVec<[u32; 4]>,
},
SparseCsr {
element: Box<DataType>,
},
SparseCoo {
element: Box<DataType>,
},
SparseBsr {
element: Box<DataType>,
block_rows: u32,
block_cols: u32,
},
F8E4M3,
F8E5M2,
I4,
FP4,
NF4,
DeviceMesh {
axes: SmallVec<[u32; 3]>,
},
Quantized {
storage: Box<DataType>,
scale: QuantizationScale,
zero_point: QuantizationZeroPoint,
},
Opaque(ExtensionDataTypeId),
}Expand description
Canonical data types supported by the vyre IR frozen data contract.
Integer-first by design. GPU floating-point is nondeterministic across
vendors through different rounding, fused multiply-add, and subnormal
handling. Integer arithmetic is deterministic everywhere. F32 is supported
for primitives that require it, with conformance validated per-backend.
vyre::ir::DataType re-exports this same type; conformance metadata should
use this canonical contract path. Example: DataType::Vec4U32 records a
four-word lane value and has a minimum byte width of 16.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
U8
Unsigned 8-bit integer.
U16
Unsigned 16-bit integer.
U32
Unsigned 32-bit integer. The fundamental GPU word.
I8
Signed 8-bit integer.
I16
Signed 16-bit integer.
I32
Signed 32-bit integer.
I64
Signed 64-bit integer.
U64
Unsigned 64-bit integer, emulated as vec2<u32> with low and high words.
Vec2U32
Two-component u32 vector.
Vec4U32
Four-component u32 vector.
Bool
Boolean value stored as a GPU word.
Bytes
Variable-length byte buffer.
Array
Fixed-element-size array.
Each element is element_size bytes. The total byte count is
N * element_size where N is encoded by the value.
F16
Strict IEEE 754 binary16 floating-point.
BF16
Strict bfloat16 floating-point.
F32
IEEE 754 binary32 floating-point.
F64
Strict IEEE 754 binary64 floating-point.
Tensor
Multi-dimensional tensor value.
Handle(TypeId)
Opaque backend resource handle.
Vec
Generic fixed-lane vector.
TensorShaped
Tensor with explicit element type and rank-limited shape.
Fields
SparseCsr
Sparse-CSR tensor: compressed sparse row layout. Element type
lives in the dense values buffer; structure (indptr + col_idx)
is laid out separately by the consumer per the documented CSR
contract. Size depends on nnz; conservative sentinel applies.
Wire encoding: tag 0x16 followed by the element type tag.
SparseCoo
Sparse-COO tensor: coordinate-list layout with (row, col, val) triples. Simpler than CSR but less cache-friendly; lowering passes typically convert COO → CSR before dispatch.
Wire encoding: tag 0x17 followed by the element type tag.
SparseBsr
Sparse-BSR tensor: block-sparse rows with fixed block size. Favored by quantized LLM weight matrices (50%+ sparsity at block-granularity retains line-rate GEMM).
Wire encoding: tag 0x18 followed by block_rows u32,
block_cols u32, then the element type tag.
Fields
F8E4M3
8-bit float (E4M3 format, per FP8 spec) for quantized inference.
F8E5M2
8-bit float (E5M2 format, per FP8 spec) - wider range than E4M3.
I4
4-bit signed integer for aggressive LLM weight quantization.
FP4
4-bit float for LLM-class inference.
NF4
4-bit “normal-float” (per QLoRA paper) for LLM weight compression.
DeviceMesh
Device-mesh handle - topology identifier consumed by
collective ops (all_reduce, all_gather, reduce_scatter,
broadcast). Shape is informational; actual topology is
resolved through the backend’s mesh registry.
Fields
Quantized
First-class quantized value domain.
storage is the physical packed element family (I4, I8, U8,
F8E4M3, NF4, etc.). scale and zero_point describe the
sidecar buffers needed to dequantize, operate, and optionally requantize
without losing the stable IR type. This closes RFC-0003 at the spec
layer; concrete ops still choose whether to lower to tensor-core MMA,
scalar dequantize-op-requantize, or a backend-specific packed path.
Fields
scale: QuantizationScaleScale sidecar layout.
zero_point: QuantizationZeroPointOptional zero-point sidecar layout.
Opaque(ExtensionDataTypeId)
Extension-declared data type.
The ExtensionDataTypeId is stable across process runs and
resolves to a &'static dyn ExtensionDataType via
vyre::dialect::extension::resolve_data_type (in vyre-core).
Wire encoding of Opaque is 0x80 ++ u32 extension_id - see
docs/wire-format.md §Extensions.
The builtin const methods on DataType (min_bytes, max_bytes,
size_bytes, is_float_family) return conservative sentinels for
Opaque because the real values live behind the trait and are not
known at compile time. Consumers that need the actual values
should resolve the trait via the vyre-core registry.
Implementations§
Source§impl DataType
impl DataType
Sourcepub const fn max_bytes(&self) -> Option<usize>
pub const fn max_bytes(&self) -> Option<usize>
Maximum byte count for one value of this type.
Returns None for truly unbounded types; currently all variants
have a hard ceiling. Fixed-width types return Some(min_bytes()).
Sourcepub const fn element_size(&self) -> Option<usize>
pub const fn element_size(&self) -> Option<usize>
Element size for array-typed outputs, or None for scalar types.
Sourcepub const fn size_bytes(&self) -> Option<usize>
pub const fn size_bytes(&self) -> Option<usize>
Fixed scalar element size in bytes, or None for variable-size types.
Scalar types return their natural width (U32 -> Some(4), Vec4U32 ->
Some(16)). Bytes returns Some(1) because each element is one byte.
Array returns Some(element_size). Tensor returns None because it
has no fixed per-element size.
Sourcepub const fn bit_width(&self) -> Option<usize>
pub const fn bit_width(&self) -> Option<usize>
True element bit width for fixed-width scalar types. Returns None
for variable / dynamically-shaped / extension-defined types.
Sub-byte types (I4, FP4, NF4) report 4 here; size_bytes
over-rounds to 1 for safety. Callers that pack two I4 per
byte (the standard layout for INT4 quantization) need
bit_width() to compute correct packed-buffer sizes:
// Allocate enough bytes to hold `count` packed `I4` values.
let bits = count.checked_mul(DataType::I4.bit_width().unwrap_or(8)).unwrap();
let bytes = bits.div_ceil(8);Sourcepub fn packed_size_bytes(
&self,
element_count: usize,
) -> Result<Option<usize>, String>
pub fn packed_size_bytes( &self, element_count: usize, ) -> Result<Option<usize>, String>
Checked packed byte count for element_count logical values.
This is the sizing helper CUDA and wire codecs should use for sub-byte
quantized storage. I4, FP4, and NF4 pack two logical elements per
byte, so packed_size_bytes(3) returns Some(2) instead of the
conservative size_bytes() * 3 == 3. Variable-width types return
Ok(None); arithmetic overflow returns an actionable error instead of
saturating.
§Errors
Returns an error when bit or byte arithmetic overflows host usize.
Source§impl DataType
impl DataType
Sourcepub fn validate_layout(&self) -> Result<(), String>
pub fn validate_layout(&self) -> Result<(), String>
Validate recursively that this data-type value is a well-formed spec contract, not merely a constructible enum value.
This rejects zero-lane vectors, zero-byte arrays, zero-sized BSR blocks, empty/non-positive device meshes, invalid quantized storage families, and zero-sized quantization groups. The enum remains constructible for migration and fuzzing, but release paths should call this before freezing signatures or allocating backend buffers.
§Errors
Returns an actionable diagnostic for the first malformed layout field.
Source§impl DataType
impl DataType
Sourcepub const fn builtin_wire_tag(&self) -> Option<u8>
pub const fn builtin_wire_tag(&self) -> Option<u8>
Frozen builtin wire tag for this data type.
Returns None for extension-declared opaque types because their wire
representation is the high-bit extension id, not a core builtin tag.
Sourcepub const fn is_float_family(&self) -> bool
pub const fn is_float_family(&self) -> bool
Whether this type belongs to the strict floating-point conformance family.
Sourcepub const fn is_quantized(&self) -> bool
pub const fn is_quantized(&self) -> bool
Whether this type carries first-class quantization sidecar metadata.
Sourcepub const fn is_quantized_storage(&self) -> bool
pub const fn is_quantized_storage(&self) -> bool
Whether this type is valid as the storage field of DataType::Quantized.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for DataType
impl<'de> Deserialize<'de> for DataType
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<DataType, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<DataType, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for DataType
Source§impl Serialize for DataType
impl Serialize for DataType
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for DataType
Auto Trait Implementations§
impl Freeze for DataType
impl RefUnwindSafe for DataType
impl Send for DataType
impl Sync for DataType
impl Unpin for DataType
impl UnsafeUnpin for DataType
impl UnwindSafe for DataType
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more