Same-node shared-memory transport with zero-copy import semantics. Publishing creates a shared-memory snapshot of model state. Importing that manifest returns tensor aliases to the shared storage instead of cloning. This proves the bridge lifecycle can expose a complete version thr
| 1694 | |
| 1695 | |
| 1696 | class SharedMemoryTensorBridge(LocalTensorCopyBridge): |
| 1697 | """ |
| 1698 | Same-node shared-memory transport with zero-copy import semantics. |
| 1699 | |
| 1700 | Publishing creates a shared-memory snapshot of model state. Importing that |
| 1701 | manifest returns tensor aliases to the shared storage instead of cloning. |
| 1702 | This proves the bridge lifecycle can expose a complete version through |
| 1703 | shared memory, while keeping the CUDA IPC transport as a separate follow-up. |
| 1704 | """ |
| 1705 | |
| 1706 | transport = "shared-memory" |
| 1707 | |
| 1708 | def __init__(self, *, source_worker: str = "local-training", source_rank: int = 0): |
| 1709 | super().__init__(source_worker=source_worker, source_rank=source_rank) |
| 1710 | self._shared_memory_segments: dict[str, dict[str, shared_memory.SharedMemory]] = {} |
| 1711 | self._owned_shared_memory_update_ids: set[str] = set() |
| 1712 | |
| 1713 | def publish( |
| 1714 | self, |
| 1715 | model: torch.nn.Module, |
| 1716 | *, |
| 1717 | weight_version: int, |
| 1718 | metadata: Optional[Mapping[str, Any]] = None, |
| 1719 | ) -> WeightUpdateManifest: |
| 1720 | user_metadata = _validated_manifest_metadata(metadata) |
| 1721 | if _BRIDGE_METADATA_KEY in user_metadata: |
| 1722 | raise WeightManifestValidationError( |
| 1723 | f"metadata key {_BRIDGE_METADATA_KEY!r} is reserved for bridge internals" |
| 1724 | ) |
| 1725 | |
| 1726 | version = int(weight_version) |
| 1727 | if version <= self._latest_published_weight_version: |
| 1728 | raise WeightManifestValidationError( |
| 1729 | "weight_version must increase monotonically " |
| 1730 | f"(got {version}, latest {self._latest_published_weight_version})" |
| 1731 | ) |
| 1732 | |
| 1733 | update_id = str(uuid.uuid4()) |
| 1734 | tensors, segments, shared_metadata = self._snapshot_to_shared_memory(model) |
| 1735 | if not tensors: |
| 1736 | for segment in segments.values(): |
| 1737 | segment.close() |
| 1738 | segment.unlink() |
| 1739 | raise WeightManifestValidationError("model state_dict produced no tensors") |
| 1740 | |
| 1741 | descriptors = { |
| 1742 | name: TensorDescriptor.from_tensor(name, tensor) for name, tensor in tensors.items() |
| 1743 | } |
| 1744 | manifest = WeightUpdateManifest( |
| 1745 | update_id=update_id, |
| 1746 | source_worker=self.source_worker, |
| 1747 | source_rank=self.source_rank, |
| 1748 | weight_version=version, |
| 1749 | transport=self.transport, |
| 1750 | tensors=descriptors, |
| 1751 | created_at=time.perf_counter(), |
| 1752 | metadata={**user_metadata, _BRIDGE_METADATA_KEY: shared_metadata}, |
| 1753 | ) |
no outgoing calls