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:
osobh
2026-07-09 19:25:51 -07:00
co-authored by Claude Fable 5
parent 64ade03ab9
commit 1e3c604896
17 changed files with 261 additions and 104 deletions
@@ -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