feat(meta,jepa): expose GPU features through meta-crates; wire JEPA cluster plan and real shard loading
Meta-crates (Phase 2): - rtx-core / rtx-training / rtx-inference-stack gain cuda and metal features threading into their sub-crates; GPU was previously unreachable through the user-facing bundles. - rtx-training restores rtx-distributed (the hpc-channels blocker is gone) so the advertised DistributedTransformerTrainer resolves; drops the unused rtx-runtime dep. - rtx-transformers drops unused rtx-backend/rtx-backend-cpu deps (stale comment referenced a teacher that never used them). Never-compiled CUDA paths fixed (surfaced by the new feature wiring, verified on RTX 5060 Ti / CUDA 13.1): - rtx-compress build.rs: missing Path/Command/fs imports. - rtx-flash-attention flash_decode_forward: reborrow &mut kernel args. - rtx-transformers: rope kernel include path, cudarc 0.18 Arc<CudaModule>, PushKernelArg imports in jepa_gpu, edition-2024 ref patterns. - rtx-memory: full cudarc 0.18 port (CudaContext, stream-based alloc, DevicePtr accessors, error enum formatting) across gpu_pinning, gpu_transfer, gpu_real, gpu_allocator/arena, gpu_tests. JEPA (Phase 3): - JepaRunConfig::apply_cluster_plan consumes ClusterTrainingPlan (batch size, TP/DP, world size, total steps) so jepa_cluster is no longer standalone dead config; ViTSizeStr::approx_params_m feeds JepaParallelConfig::for_model_and_cluster. - WebDatasetShard::load reads real .tar shards from disk via the existing parser (gzip rejected explicitly); to_in_memory documented as synthetic/test-only. - New image-decode feature actually defines the dep for the previously unreachable cfg(feature = "image-decode") JPEG/PNG decode path. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -728,10 +728,12 @@ impl DatasetStats {
|
||||
// WebDatasetShard
|
||||
// ============================================================================
|
||||
|
||||
/// Filesystem shard descriptor for WebDataset-format `.tar` / `.tar.gz` archives.
|
||||
/// Filesystem shard descriptor for WebDataset-format `.tar` archives.
|
||||
///
|
||||
/// In production this would open and iterate over the tar archive.
|
||||
/// This stub stores metadata and generates synthetic data for `to_in_memory`.
|
||||
/// Use [`WebDatasetShard::load`] to read the actual archive from disk
|
||||
/// (via [`read_webdataset_shard`]); [`WebDatasetShard::to_in_memory`]
|
||||
/// generates synthetic data and exists for tests that need a shard
|
||||
/// without touching the filesystem.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WebDatasetShard {
|
||||
pub path: String,
|
||||
@@ -754,9 +756,33 @@ impl WebDatasetShard {
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the shard's `.tar` archive from disk and decode its records
|
||||
/// into an [`InMemoryShard`].
|
||||
///
|
||||
/// Gzip-compressed shards (`.tar.gz`/`.tgz`) are not yet supported and
|
||||
/// return an error rather than mis-parsing.
|
||||
pub fn load(&self) -> Result<InMemoryShard, String> {
|
||||
if self.compressed {
|
||||
return Err(format!(
|
||||
"compressed shard not supported yet (gzip): {}",
|
||||
self.path
|
||||
));
|
||||
}
|
||||
let (raw_records, _stats) =
|
||||
read_webdataset_shard(std::path::Path::new(&self.path))?;
|
||||
let records: Vec<ImageRecord> = raw_records
|
||||
.into_iter()
|
||||
.map(webdataset_record_to_image)
|
||||
.collect();
|
||||
Ok(InMemoryShard {
|
||||
records,
|
||||
shard_id: self.shard_id,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a synthetic `InMemoryShard` with `num_records` records of
|
||||
/// size `image_size × image_size × 3`. Used for testing without a
|
||||
/// real filesystem.
|
||||
/// real filesystem — use [`WebDatasetShard::load`] for real data.
|
||||
pub fn to_in_memory(&self, image_size: usize) -> InMemoryShard {
|
||||
InMemoryShard::synthetic(self.num_records, image_size, self.shard_id)
|
||||
}
|
||||
@@ -1750,6 +1776,31 @@ mod tests {
|
||||
|
||||
// ── Tar parsing tests ─────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn test_webdataset_shard_load_reads_real_tar() {
|
||||
// Write a real tar to a temp file and load it through WebDatasetShard.
|
||||
let fake_jpg = b"\xFF\xD8\xFF\xE0fake jpeg content";
|
||||
let tar = make_test_tar(&[("000000", fake_jpg, Some(7)), ("000001", fake_jpg, None)]);
|
||||
let dir = std::env::temp_dir();
|
||||
let path = dir.join(format!("jepa_shard_load_test_{}.tar", std::process::id()));
|
||||
std::fs::write(&path, &tar).expect("write temp tar");
|
||||
|
||||
let shard = WebDatasetShard::new(path.to_str().unwrap(), 2, 3);
|
||||
let mem = shard.load().expect("load real tar");
|
||||
std::fs::remove_file(&path).ok();
|
||||
|
||||
assert_eq!(mem.shard_id, 3);
|
||||
assert_eq!(mem.records.len(), 2);
|
||||
assert_eq!(mem.records[0].label, Some(7));
|
||||
assert_eq!(mem.records[1].label, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_webdataset_shard_load_rejects_gzip() {
|
||||
let shard = WebDatasetShard::new("/tmp/whatever.tar.gz", 1, 0);
|
||||
assert!(shard.load().is_err(), "gzip shards must be rejected, not mis-parsed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_empty_tar() {
|
||||
// Two zero blocks = empty archive
|
||||
|
||||
Reference in New Issue
Block a user