Skip to main content

StreamWriter

Struct StreamWriter 

Source
pub struct StreamWriter<W> { /* private fields */ }
Expand description

Writes tensors to an async sink in the Hurray streaming wire format.

The wire format is bare concatenation: each tensor is represented as its encoded [TensorDescriptor] immediately followed by each buffer’s raw bytes. No outer framing, no alignment padding between tensors.

§Examples

use hurray_core::{
    BufferHandle, DeviceTag, ElementType, LayoutDescriptor, Shape, SyncMode,
    TensorDescriptor, MIN_BUFFER_ALIGNMENT,
};
use hurray_io::stream::StreamWriter;

let handle = BufferHandle::new(64, MIN_BUFFER_ALIGNMENT, DeviceTag::Cpu, SyncMode::ProducerSynced)?;
let shape = Shape::new(vec![4u64, 4]).unwrap();
let desc = TensorDescriptor::new(
    1, 0,
    ElementType::Float32,
    shape,
    0,
    LayoutDescriptor::RowMajor,
    vec![handle],
    None, None, None, None,
)?;
let data = vec![0u8; 64];

let mut wire = Vec::<u8>::new();
let mut writer = StreamWriter::new(&mut wire);
writer.write_tensor(&desc, &[&data]).await?;
writer.finish().await?;

Implementations§

Source§

impl<W: AsyncWrite + Unpin> StreamWriter<W>

Source

pub fn new(inner: W) -> Self

Creates a writer that accepts any valid [SyncMode].

Source

pub fn cross_machine(inner: W) -> Self

Creates a writer that rejects buffers whose sync_mode is not [SyncMode::ProducerSynced].

Use this when the stream crosses machine boundaries where GPU and semaphore-based sync primitives are not transferable.

Source

pub async fn write_tensor( &mut self, desc: &TensorDescriptor, buffers: &[&[u8]], ) -> Result<()>

Encodes and writes one tensor.

§Errors
Source

pub async fn write_composite( &mut self, head: &TensorDescriptor, members: &[CompositeNode<'_>], ) -> Result<()>

Encodes and writes a composite tensor: its head followed by every member’s descriptor and data, in order (ADR-027 § Binding).

The group is validated before any byte is written — reusing [CompositeValidator] to check member_count and the per-rule constraints (partition exact-cover / non-overlap, overlay base-first ordering) — so a torn or invalid composite never reaches the wire. Members that are themselves composites are written recursively (head precedes its members at every level), preserving the forward, self-delimiting, back-reference-free wire contract.

§Examples
use hurray_core::{
    layout::{CompositeLayout, CompositionRule, LayoutDescriptor},
    ElementType, Shape, ShardDescriptor, TensorDescriptor,
};
use hurray_io::stream::{CompositeNode, StreamWriter};

// A partition head [8, 8] split into two [8, 4] members (buffers elided here).
let head = TensorDescriptor::new(
    1, 0, ElementType::Float32, Shape::new(vec![8u64, 8]).unwrap(), 0,
    LayoutDescriptor::Composite(CompositeLayout::new(CompositionRule::Partition, 2).unwrap()),
    vec![], None, None, None, None,
)?;
let mut wire = Vec::<u8>::new();
let mut writer = StreamWriter::new(&mut wire);
writer.write_composite(&head, &members).await?;
writer.finish().await?;
§Errors
  • Error::Core — the head is not a valid composite head, or validation failed (member-count mismatch, partition coverage, overlay ordering)
  • the same buffer/sync errors as write_tensor for each member
  • Error::Io — underlying write error
Source

pub async fn finish(self) -> Result<W>

Flushes the underlying sink and returns it.

Auto Trait Implementations§

§

impl<W> Freeze for StreamWriter<W>
where W: Freeze,

§

impl<W> RefUnwindSafe for StreamWriter<W>
where W: RefUnwindSafe,

§

impl<W> Send for StreamWriter<W>
where W: Send,

§

impl<W> Sync for StreamWriter<W>
where W: Sync,

§

impl<W> Unpin for StreamWriter<W>
where W: Unpin,

§

impl<W> UnsafeUnpin for StreamWriter<W>
where W: UnsafeUnpin,

§

impl<W> UnwindSafe for StreamWriter<W>
where W: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.