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.

This is a driver, not an encoder: StreamWriterCore holds the wire format and emits the bytes, and this type only hands them to the sink (ADR-041 § 7). Payloads are never assembled or copied on the way — each slice goes to the sink as it is (§ 3).

§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 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

A failure before the first byte of this tensor leaves the writer usable, so the same tensor may be written again; a failure after it poisons the writer, because a truncated item is on the wire and a stream has no resynchronisation point (§ 6b).

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 as part of the same operation (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/sink 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.