import os
import re
with open("src/pipeline.rs", "r") as f:
text = f.read()
def extract(pattern, end_marker=None):
match = re.search(pattern, text)
if not match:
return ""
start = match.start()
if end_marker:
end_match = re.search(end_marker, text[start:])
if end_match:
return text[start:start+end_match.end()]
brace_level = 0
in_block = False
for i in range(start, len(text)):
if text[i] == '{':
if not in_block:
in_block = True
brace_level += 1
elif text[i] == '}':
brace_level -= 1
if in_block and brace_level == 0:
return text[start:i+1]
return text[start:]
def write_mod(filename, content):
with open("src/pipeline/" + filename, "w") as f:
f.write("#![allow(clippy::module_name_repetitions)]\n\n")
f.write("use crate::error::{Error, Result};\n")
f.write("use crate::sample::{DType, Sample, Tensor};\n")
f.write("use crate::source::Source;\n")
f.write("use crate::transform::*;\n")
f.write("use super::*;\n")
f.write("use std::collections::BTreeMap;\n")
f.write("use std::panic::{catch_unwind, AssertUnwindSafe};\n")
f.write("use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};\n")
f.write("use std::sync::Arc;\n")
f.write("use std::time::{Duration, Instant};\n")
f.write("use crossbeam_channel::{bounded, Receiver, RecvTimeoutError, Sender};\n")
f.write("use std::any::Any;\n\n")
f.write(content)
os.makedirs("src/pipeline", exist_ok=True)
config = extract(r"/// Configuration for the pipeline\.\n#\[derive\(Debug, Clone\)\]\npub struct PipelineConfig")
config += "\n\n" + extract(r"/// What to do when a data loading error occurs\.\n#\[non_exhaustive\]\n#\[derive\(Debug, Clone, Copy, PartialEq, Eq\)\]\npub enum ErrorPolicy")
config += "\n\n" + extract(r"impl Default for PipelineConfig")
write_mod("config.rs", config)
types = "pub(crate) type CollateFn = dyn Fn(Vec<Sample>) -> Result<Sample> + Send + Sync + 'static;\n\n"
types += extract(r"enum Stage") + "\n\n"
types += extract(r"enum CollectorStage") + "\n\n"
types += extract(r"enum CollectorItem") + "\n\n"
types += extract(r"struct SampleChunk") + "\n\n"
types += extract(r"enum SourceMessage") + "\n\n"
types += extract(r"enum CollateMode") + "\n\n"
types = types.replace("enum ", "pub(crate) enum ").replace("struct SampleChunk", "pub(crate) struct SampleChunk")
types = types.replace("CollectorStage::", "crate::pipeline::core_types::CollectorStage::")
write_mod("core_types.rs", types)
iterator = extract(r"/// A running pipeline that yields batches of samples\.\npub struct PipelineIterator")
iterator += "\n\n" + extract(r"/// Error returned when waiting for the next batch with a timeout\.\n#\[derive\(Debug, Clone, Copy, PartialEq, Eq\)\]\npub enum NextTimeoutError")
iterator += "\n\n" + extract(r"impl PipelineIterator")
iterator += "\n\n" + extract(r"impl Iterator for PipelineIterator")
iterator += "\n\n" + extract(r"impl Drop for PipelineIterator")
iterator += "\n\n" + extract(r"/// Observability snapshot from a running or completed pipeline\.\n#\[derive\(Debug, Clone\)\]\npub struct PipelineStats")
iterator += "\n\n" + extract(r"impl std::fmt::Display for PipelineStats")
write_mod("iterator.rs", iterator)
collate = extract(r"fn collate_batch")
collate += "\n\n" + extract(r"fn default_collate")
collate = collate.replace("fn collate_batch", "pub(crate) fn collate_batch").replace("fn default_collate", "pub(crate) fn default_collate")
write_mod("collate.rs", collate)
worker = extract(r"fn apply_stateless")
worker = worker.replace("fn apply_stateless", "pub(crate) fn apply_stateless")
write_mod("worker.rs", worker)
collector = extract(r"fn push_collector_stage")
collector += "\n\n" + extract(r"fn finish_collector_stage")
collector += "\n\n" + extract(r"fn emit_items")
collector += "\n\n" + extract(r"fn handle_collector_error")
collector = collector.replace("fn push_", "pub(crate) fn push_") \
.replace("fn finish_", "pub(crate) fn finish_") \
.replace("fn emit_items", "pub(crate) fn emit_items") \
.replace("fn handle_collector_error", "pub(crate) fn handle_collector_error")
write_mod("collector.rs", collector)
thrd = extract(r"fn recv_source_message")
thrd += "\n\n" + extract(r"fn run_source_epoch")
thrd += "\n\n" + extract(r"fn run_source_iterator")
thrd = thrd.replace("fn recv_source_message", "pub(crate) fn recv_source_message") \
.replace("fn run_source_epoch", "pub(crate) fn run_source_epoch") \
.replace("fn run_source_iterator", "pub(crate) fn run_source_iterator")
write_mod("source_thread.rs", thrd)
utils = extract(r"fn wrap_source")
utils += "\n\n" + extract(r"fn validate_stage_order")
utils += "\n\n" + extract(r"fn panic_message")
utils += "\n\n" + extract(r"fn num_cpus")
utils = utils.replace("fn wrap_source", "pub(crate) fn wrap_source") \
.replace("fn validate_stage_order", "pub(crate) fn validate_stage_order") \
.replace("fn panic_message", "pub(crate) fn panic_message") \
.replace("fn num_cpus", "pub(crate) fn num_cpus")
write_mod("utils.rs", utils)
builder = extract(r"/// A composable data loading pipeline\.\n///\n/// Build it with \[`Pipeline::from_source`\], chain transforms, then iterate\.\npub struct Pipeline")
builder += "\n\n" + extract(r"impl Pipeline")
write_mod("builder.rs", builder)
mod_rs = """//! Pipeline - the composable data loading engine.
//!
//! A pipeline is a chain: `Source -> [Workers] -> [Collector] -> Consumer`.
//! Multiple worker threads load data and apply stateless transforms in parallel.
//! A single collector thread applies ordering-sensitive stages such as shuffle,
//! batching, and collation.
pub mod config;
pub mod core_types;
pub mod collate;
pub mod collector;
pub mod iterator;
pub mod source_thread;
pub mod utils;
pub mod worker;
pub mod builder;
pub use config::{PipelineConfig, ErrorPolicy};
pub use builder::Pipeline;
pub use iterator::{PipelineIterator, NextTimeoutError, PipelineStats};
pub(crate) use core_types::*;
pub(crate) use collate::*;
pub(crate) use collector::*;
pub(crate) use source_thread::*;
pub(crate) use utils::*;
pub(crate) use worker::*;
"""
with open("src/pipeline/mod.rs", "w") as f:
f.write(mod_rs)
with open("src/pipeline.rs", "w") as f:
f.write("pub mod pipeline;\npub use pipeline::*;\n")