spmd_types 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {spmd_types-0.3.1/spmd_types.egg-info → spmd_types-0.3.2}/PKG-INFO +1 -1
- spmd_types-0.3.2/pyproject.toml +110 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_collectives.py +57 -15
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_local.py +6 -4
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/rules.py +4 -1
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/types.py +3 -1
- {spmd_types-0.3.1 → spmd_types-0.3.2/spmd_types.egg-info}/PKG-INFO +1 -1
- spmd_types-0.3.1/pyproject.toml +0 -69
- {spmd_types-0.3.1 → spmd_types-0.3.2}/LICENSE +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/README.md +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/setup.cfg +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/__init__.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_backward_hooks.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_checker/__init__.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_coverage.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_dist.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_dtensor.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_dtensor_checker.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_dtype_utils.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_frame.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_local_registration.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_mesh.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_mesh_axis.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_mesh_region.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_raw_dist.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_reinterpret_mesh.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_scalar.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_scalar_sentinel.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_state.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_test_utils.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_testing.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_traceback.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_type_attr.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/_vmap.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/checker.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/py.typed +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/rulecheck.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types/runtime.py +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types.egg-info/SOURCES.txt +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types.egg-info/dependency_links.txt +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types.egg-info/requires.txt +0 -0
- {spmd_types-0.3.1 → spmd_types-0.3.2}/spmd_types.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "spmd_types"
|
|
7
|
+
version = "0.3.2"
|
|
8
|
+
description = "A type system for distributed (SPMD) tensor computations in PyTorch"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {file = "LICENSE"}
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Meta Platforms, Inc."},
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"License :: OSI Approved :: BSD License",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
docs = [
|
|
31
|
+
"myst-parser==2.0.0",
|
|
32
|
+
"pytorch-sphinx-theme2==0.4.13",
|
|
33
|
+
"sphinx==7.2.6",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/meta-pytorch/spmd_types"
|
|
38
|
+
Documentation = "https://meta-pytorch.org/spmd_types/"
|
|
39
|
+
Repository = "https://github.com/meta-pytorch/spmd_types"
|
|
40
|
+
Issues = "https://github.com/meta-pytorch/spmd_types/issues"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
include = ["spmd_types*"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
spmd_types = ["py.typed"]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
line-length = 88
|
|
51
|
+
target-version = "py310"
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = ["E4", "E7", "E9", "F"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff.format]
|
|
57
|
+
exclude = ["*.md"]
|
|
58
|
+
quote-style = "double"
|
|
59
|
+
|
|
60
|
+
[tool.pytest.ini_options]
|
|
61
|
+
testpaths = ["tests"]
|
|
62
|
+
python_files = ["*_test.py"]
|
|
63
|
+
|
|
64
|
+
# ops imports spmd_types from most of its interfaces and farm from its
|
|
65
|
+
# gradient code, so an unscoped import graph selects their suites, GPU plans
|
|
66
|
+
# included, for every change here. Import-graph selection stays inside this
|
|
67
|
+
# tree; the tests below opt back in.
|
|
68
|
+
[tool.test-selector.graph-dependents]
|
|
69
|
+
"**" = ["**"]
|
|
70
|
+
|
|
71
|
+
[tool.test-selector.extra-deps]
|
|
72
|
+
|
|
73
|
+
# The farm tests that import spmd_types directly.
|
|
74
|
+
"**" = [
|
|
75
|
+
"../farm/farm/model/tests/test_input_side_fsdp_order.py",
|
|
76
|
+
"../farm/farm/optimize/tests/test_grad_clipping_shared_tensor.py",
|
|
77
|
+
"../farm/farm/optimize/tests/test_replication_metadata.py",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
# BEGIN GENERATED buck-manual-deps -- do not edit by hand
|
|
81
|
+
# Regenerate: export_buck_manual_deps.py
|
|
82
|
+
"spmd_types/__init__.py" = [
|
|
83
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_artifacts.py",
|
|
84
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_artifacts_v22.py",
|
|
85
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_encoder_r6_i11_v22.py",
|
|
86
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_conditioner_calibration_v21.py",
|
|
87
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_ctts_pipeline_r6_i11_v22.py",
|
|
88
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_recipe_r5_v21.py",
|
|
89
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r5.py",
|
|
90
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r6_i11_v22.py",
|
|
91
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r6_i11_v22_gb300.py",
|
|
92
|
+
"../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_style_r5_v21.py",
|
|
93
|
+
"../ops/interfaces/attn/triton_attention_fp32.py",
|
|
94
|
+
"../ops/interfaces/gemm/gemm.py",
|
|
95
|
+
"../rl/projects/rvg/data/data_pipeline/kimi_labeling.py",
|
|
96
|
+
]
|
|
97
|
+
# END GENERATED buck-manual-deps
|
|
98
|
+
|
|
99
|
+
[dependency-groups]
|
|
100
|
+
# Build backend of this package, locked: in the mslsrc/tbd_training export the
|
|
101
|
+
# members build against the venv (the root's `no-build-isolation-package`), so
|
|
102
|
+
# the backend has to be in a default group for `uv sync` to install it first.
|
|
103
|
+
build = ["setuptools", "wheel"]
|
|
104
|
+
# What the tests import beyond the package itself; the export runs them in
|
|
105
|
+
# this project's uv env.
|
|
106
|
+
# @tbd-training-enable: dev = ["expecttest", "pytest", "torch"]
|
|
107
|
+
|
|
108
|
+
[tool.uv]
|
|
109
|
+
default-groups = ["build"] # @tbd-training-disable
|
|
110
|
+
# @tbd-training-enable: default-groups = ["build", "dev"]
|
|
@@ -68,11 +68,12 @@ class _AllReduce(torch.autograd.Function):
|
|
|
68
68
|
ctx.backward_options = dtype_options.backward_options
|
|
69
69
|
if inplace:
|
|
70
70
|
assert dtype_options.op_dtype == x.dtype
|
|
71
|
+
# c10d reduces x's own storage, which must be contiguous.
|
|
72
|
+
# funcol.all_reduce copies strided inputs itself.
|
|
73
|
+
assert x.is_contiguous(), "inplace all_reduce input must be contiguous"
|
|
71
74
|
else:
|
|
72
75
|
x = _apply_op_dtype(x, dtype_options.op_dtype)
|
|
73
76
|
pg = axis
|
|
74
|
-
# TODO: check if contiguous assertion is really necessary
|
|
75
|
-
assert x.is_contiguous(), "all_reduce input must be contiguous"
|
|
76
77
|
# TODO: check if world_size == 1 short-circuit is really necessary
|
|
77
78
|
if _dist.dist.get_world_size(pg) == 1:
|
|
78
79
|
if inplace:
|
|
@@ -241,7 +242,7 @@ def all_reduce(
|
|
|
241
242
|
input_dtype=x.dtype,
|
|
242
243
|
requires_grad=x.requires_grad,
|
|
243
244
|
async_op=async_op,
|
|
244
|
-
input_is_leaf=x.requires_grad and x.
|
|
245
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
245
246
|
inplace=inplace,
|
|
246
247
|
)
|
|
247
248
|
return _AllReduce.apply(x, pg, dst, inplace, dtype_options)
|
|
@@ -603,7 +604,7 @@ def all_gather(
|
|
|
603
604
|
input_dtype=x.dtype,
|
|
604
605
|
requires_grad=x.requires_grad,
|
|
605
606
|
async_op=async_op,
|
|
606
|
-
input_is_leaf=x.requires_grad and x.
|
|
607
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
607
608
|
)
|
|
608
609
|
if split_sizes is not None:
|
|
609
610
|
return _AllGatherUneven.apply(
|
|
@@ -640,7 +641,10 @@ class _ReduceScatterStack(torch.autograd.Function):
|
|
|
640
641
|
# NCCL reduce_scatter_tensor always scatters along dim 0, so move
|
|
641
642
|
# scatter_dim into position 0 when it isn't already there.
|
|
642
643
|
if scatter_dim != 0:
|
|
643
|
-
x = x.movedim(scatter_dim, 0)
|
|
644
|
+
x = x.movedim(scatter_dim, 0)
|
|
645
|
+
# NCCL reduce_scatter_tensor reads the input as contiguous without
|
|
646
|
+
# checking; incoming gradients (e.g. from sum()) can be expanded views.
|
|
647
|
+
x = x.contiguous()
|
|
644
648
|
result = x.new_empty([1] + list(x.shape[1:]))
|
|
645
649
|
_dist.dist.reduce_scatter_tensor(
|
|
646
650
|
result, x, op=_dist.dist.ReduceOp.SUM, group=pg
|
|
@@ -882,7 +886,7 @@ def reduce_scatter(
|
|
|
882
886
|
input_dtype=x.dtype,
|
|
883
887
|
requires_grad=x.requires_grad,
|
|
884
888
|
async_op=async_op,
|
|
885
|
-
input_is_leaf=x.requires_grad and x.
|
|
889
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
886
890
|
)
|
|
887
891
|
|
|
888
892
|
if dst is V:
|
|
@@ -915,7 +919,9 @@ class _AllToAllStack(torch.autograd.Function):
|
|
|
915
919
|
ctx.backward_options = dtype_options.backward_options
|
|
916
920
|
x = _apply_op_dtype(x, dtype_options.op_dtype)
|
|
917
921
|
pg = axis
|
|
918
|
-
|
|
922
|
+
# Process groups require contiguous chunks; unbind along a non-zero
|
|
923
|
+
# split_dim returns strided views.
|
|
924
|
+
input_chunks = [c.contiguous() for c in torch.unbind(x, dim=split_dim)]
|
|
919
925
|
output_chunks = [
|
|
920
926
|
torch.empty_like(input_chunks[0]) for _ in range(len(input_chunks))
|
|
921
927
|
]
|
|
@@ -1045,6 +1051,7 @@ def all_to_all(
|
|
|
1045
1051
|
::
|
|
1046
1052
|
|
|
1047
1053
|
def all_to_all_spec(xs, src, dst):
|
|
1054
|
+
n = mesh_axis_size
|
|
1048
1055
|
match src, dst:
|
|
1049
1056
|
case V, V:
|
|
1050
1057
|
x = torch.stack(xs)
|
|
@@ -1052,8 +1059,13 @@ def all_to_all(
|
|
|
1052
1059
|
return x.unbind()
|
|
1053
1060
|
|
|
1054
1061
|
case S(i), S(j):
|
|
1055
|
-
|
|
1056
|
-
|
|
1062
|
+
# Every rank splits its tensor into n chunks on dim j and
|
|
1063
|
+
# sends chunk r to rank r; rank r concatenates the chunks
|
|
1064
|
+
# it receives on dim i, in source rank order.
|
|
1065
|
+
return [
|
|
1066
|
+
torch.concat([x.chunk(n, j)[r] for x in xs], i)
|
|
1067
|
+
for r in range(n)
|
|
1068
|
+
]
|
|
1057
1069
|
|
|
1058
1070
|
The varying and shard versions of ``all_to_all`` are pretty different (even
|
|
1059
1071
|
though under the hood they both have an all-to-all communication pattern),
|
|
@@ -1062,8 +1074,33 @@ def all_to_all(
|
|
|
1062
1074
|
* ``all_to_all(V,V)`` transposes the logical mesh axis with the dim 0 local
|
|
1063
1075
|
tensor axis.
|
|
1064
1076
|
|
|
1065
|
-
* ``all_to_all(S(i),S(j))`` intuitively unshards the tensor
|
|
1066
|
-
then reshards it on dim j (but skips actually doing the
|
|
1077
|
+
* ``all_to_all(S(i),S(j))`` with ``i != j`` intuitively unshards the tensor
|
|
1078
|
+
on dim i, and then reshards it on dim j (but skips actually doing the
|
|
1079
|
+
all-gather). The global tensor is preserved:
|
|
1080
|
+
``torch.concat(ys, j) == torch.concat(xs, i)``.
|
|
1081
|
+
|
|
1082
|
+
* ``all_to_all(S(i),S(i))`` does the same exchange with split and concat on
|
|
1083
|
+
the same dim. The output is still ``S(i)``, but the global tensor is
|
|
1084
|
+
block-permuted: view global dim i as ``n * n`` equal blocks indexed by
|
|
1085
|
+
(source rank, destination rank); the exchange swaps the two indices.
|
|
1086
|
+
With ``x = torch.concat(xs, i)`` and ``y = torch.concat(ys, i)``::
|
|
1087
|
+
|
|
1088
|
+
y = x.unflatten(i, (n, n, -1)).transpose(i, i + 1).flatten(i, i + 2)
|
|
1089
|
+
|
|
1090
|
+
For example, if two ranks hold ``[0, 1, 2, 3]`` and ``[4, 5, 6, 7]``,
|
|
1091
|
+
they end up with ``[0, 1, 4, 5]`` and ``[2, 3, 6, 7]``: the global tensor
|
|
1092
|
+
goes from ``[0, 1, 2, 3, 4, 5, 6, 7]`` to ``[0, 1, 4, 5, 2, 3, 6, 7]``.
|
|
1093
|
+
This is a valid global SPMD operation. ``S(i)`` says how the global
|
|
1094
|
+
tensor is reconstructed from the local tensors; it does not promise that
|
|
1095
|
+
a collective leaves the global value unchanged. Each explicit collective
|
|
1096
|
+
defines its own operation on the global tensor, which may depend on the
|
|
1097
|
+
size of the mesh axis. Use ``redistribute`` to change the type while
|
|
1098
|
+
preserving the global value; ``redistribute(S(i),S(i))`` is a no-op.
|
|
1099
|
+
|
|
1100
|
+
With ``input_split_sizes``/``output_split_sizes`` (all-to-all-v), the
|
|
1101
|
+
exchange is the same on dim 0 except that rank s sends its
|
|
1102
|
+
``input_split_sizes[r]`` rows to rank r, so in general it moves blocks of
|
|
1103
|
+
the global tensor rather than preserving it.
|
|
1067
1104
|
|
|
1068
1105
|
::
|
|
1069
1106
|
|
|
@@ -1122,7 +1159,8 @@ def all_to_all(
|
|
|
1122
1159
|
[C0, C1, C2] [A2, B2, C2]
|
|
1123
1160
|
|
|
1124
1161
|
``all_to_all(S(i),S(j)): S(i) -> S(j)``, the backwards is
|
|
1125
|
-
``all_to_all(S(j),S(i)): S(j) -> S(i)``.
|
|
1162
|
+
``all_to_all(S(j),S(i)): S(j) -> S(i)``. When ``i == j`` this is the same
|
|
1163
|
+
block transpose, which is its own inverse.
|
|
1126
1164
|
"""
|
|
1127
1165
|
pg = _pg_for_axis(axis)
|
|
1128
1166
|
if has_torch_function_unary(x):
|
|
@@ -1154,7 +1192,7 @@ def all_to_all(
|
|
|
1154
1192
|
|
|
1155
1193
|
if isinstance(src, Shard) and isinstance(dst, Shard):
|
|
1156
1194
|
# S(i) -> S(j): physically split on new shard dim (j), concat on old (i).
|
|
1157
|
-
#
|
|
1195
|
+
# This preserves the global tensor only when i != j; see the docstring.
|
|
1158
1196
|
if split_dim is not None and split_dim != dst.dim:
|
|
1159
1197
|
raise ValueError(
|
|
1160
1198
|
f"all_to_all S({src.dim})->S({dst.dim}) got split_dim={split_dim} "
|
|
@@ -1200,7 +1238,7 @@ def all_to_all(
|
|
|
1200
1238
|
input_dtype=x.dtype,
|
|
1201
1239
|
requires_grad=x.requires_grad,
|
|
1202
1240
|
async_op=async_op,
|
|
1203
|
-
input_is_leaf=x.requires_grad and x.
|
|
1241
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
1204
1242
|
)
|
|
1205
1243
|
|
|
1206
1244
|
if output_split_sizes is not None or input_split_sizes is not None:
|
|
@@ -1250,7 +1288,11 @@ def redistribute( # noqa: C901
|
|
|
1250
1288
|
redistribute(P,R) = all_reduce(P,R)
|
|
1251
1289
|
redistribute(P,I) = all_reduce(P,I)
|
|
1252
1290
|
redistribute(P,S(i)) = reduce_scatter(P,S(i))
|
|
1253
|
-
redistribute(S(i),S(j)) = all_to_all(S(i),S(j))
|
|
1291
|
+
redistribute(S(i),S(j)) = all_to_all(S(i),S(j)) (i != j)
|
|
1292
|
+
redistribute(S(i),S(i)) = x (no-op)
|
|
1293
|
+
|
|
1294
|
+
``redistribute(S(i),S(i))`` does not route to ``all_to_all(S(i),S(i))``,
|
|
1295
|
+
which block-permutes the global tensor (see ``all_to_all``).
|
|
1254
1296
|
|
|
1255
1297
|
These only work if the mesh axis is the LAST to shard a particular tensor
|
|
1256
1298
|
dimension.
|
|
@@ -62,7 +62,8 @@ def _build_rank_to_group_local(pg) -> dict[int, int]:
|
|
|
62
62
|
- Groups are [0,1] and [2,3]
|
|
63
63
|
- Returns {0: 0, 1: 1, 2: 0, 3: 1}
|
|
64
64
|
"""
|
|
65
|
-
|
|
65
|
+
# Older torch also returns the group's base offset as a third element.
|
|
66
|
+
ranks, group_offsets = _prepare_collective_groups(pg)[:2]
|
|
66
67
|
mapping = {}
|
|
67
68
|
for group_offset in group_offsets:
|
|
68
69
|
for local_rank, r in enumerate(ranks):
|
|
@@ -402,7 +403,7 @@ def reinterpret( # noqa: C901
|
|
|
402
403
|
input_dtype=x.dtype,
|
|
403
404
|
requires_grad=x.requires_grad,
|
|
404
405
|
async_op=async_op,
|
|
405
|
-
input_is_leaf=x.requires_grad and x.
|
|
406
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
406
407
|
)
|
|
407
408
|
|
|
408
409
|
if src is R and dst is V:
|
|
@@ -1099,7 +1100,7 @@ def convert( # noqa: C901
|
|
|
1099
1100
|
input_dtype=x.dtype,
|
|
1100
1101
|
requires_grad=x.requires_grad,
|
|
1101
1102
|
async_op=async_op,
|
|
1102
|
-
input_is_leaf=x.requires_grad and x.
|
|
1103
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
1103
1104
|
)
|
|
1104
1105
|
|
|
1105
1106
|
if src_base is R and dst_base is V:
|
|
@@ -1184,6 +1185,7 @@ def shard(
|
|
|
1184
1185
|
)
|
|
1185
1186
|
|
|
1186
1187
|
|
|
1188
|
+
@api_boundary
|
|
1187
1189
|
def invariant_to_replicate(
|
|
1188
1190
|
x,
|
|
1189
1191
|
axis: DeviceMeshAxis,
|
|
@@ -1245,6 +1247,6 @@ def invariant_to_replicate(
|
|
|
1245
1247
|
input_dtype=x.dtype,
|
|
1246
1248
|
requires_grad=x.requires_grad,
|
|
1247
1249
|
async_op=async_op,
|
|
1248
|
-
input_is_leaf=x.requires_grad and x.
|
|
1250
|
+
input_is_leaf=x.requires_grad and x.is_leaf,
|
|
1249
1251
|
)
|
|
1250
1252
|
return _InvariantToReplicate.apply(x, axis, dtype_options)
|
|
@@ -851,7 +851,10 @@ def all_to_all(
|
|
|
851
851
|
dst: PerMeshAxisSpmdType = V,
|
|
852
852
|
out: torch.Tensor | None = None,
|
|
853
853
|
) -> torch.Tensor | NdimWithSpmdType:
|
|
854
|
-
"""Type of ``spmd.all_to_all(x, axis, src=, dst=)``: ``V|S(i) -> V|S(j)``.
|
|
854
|
+
"""Type of ``spmd.all_to_all(x, axis, src=, dst=)``: ``V|S(i) -> V|S(j)``.
|
|
855
|
+
|
|
856
|
+
``i == j`` is accepted, as at runtime; see ``spmd.all_to_all`` for its
|
|
857
|
+
global semantics (a block permutation of the global tensor)."""
|
|
855
858
|
return _transition(x, "all_to_all", axis, src, dst, [("V|S", "V|S")], out=out)
|
|
856
859
|
|
|
857
860
|
|
|
@@ -70,7 +70,9 @@ class Shard:
|
|
|
70
70
|
specifying how ranks relate to a global tensor, Shard(dim) additionally
|
|
71
71
|
says "the global tensor can be reconstructed by concatenating the local
|
|
72
72
|
tensors along dimension ``dim``." This is analogous to DTensor's
|
|
73
|
-
``Shard(dim)`` placement.
|
|
73
|
+
``Shard(dim)`` placement. It describes how to reconstruct the global
|
|
74
|
+
tensor, not that an operation from ``S(i)`` to ``S(i)`` preserves its value
|
|
75
|
+
(e.g., ``all_to_all(S(i), S(i))`` block-permutes the global tensor).
|
|
74
76
|
|
|
75
77
|
This is not a true type (notice it doesn't inherit from PerMeshAxisLocalSpmdType)
|
|
76
78
|
but it is accepted at any src/dst argument and, from a typing perspective,
|
spmd_types-0.3.1/pyproject.toml
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "spmd_types"
|
|
7
|
-
version = "0.3.1"
|
|
8
|
-
description = "A type system for distributed (SPMD) tensor computations in PyTorch"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = {file = "LICENSE"}
|
|
11
|
-
requires-python = ">=3.10"
|
|
12
|
-
authors = [
|
|
13
|
-
{name = "Meta Platforms, Inc."},
|
|
14
|
-
]
|
|
15
|
-
classifiers = [
|
|
16
|
-
"Development Status :: 4 - Beta",
|
|
17
|
-
"Intended Audience :: Developers",
|
|
18
|
-
"Intended Audience :: Science/Research",
|
|
19
|
-
"License :: OSI Approved :: BSD License",
|
|
20
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
-
"Programming Language :: Python :: 3.10",
|
|
22
|
-
"Programming Language :: Python :: 3.11",
|
|
23
|
-
"Programming Language :: Python :: 3.12",
|
|
24
|
-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
25
|
-
]
|
|
26
|
-
dependencies = [
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
[project.optional-dependencies]
|
|
30
|
-
docs = [
|
|
31
|
-
"myst-parser==2.0.0",
|
|
32
|
-
"pytorch-sphinx-theme2==0.4.13",
|
|
33
|
-
"sphinx==7.2.6",
|
|
34
|
-
]
|
|
35
|
-
|
|
36
|
-
[project.urls]
|
|
37
|
-
Homepage = "https://github.com/meta-pytorch/spmd_types"
|
|
38
|
-
Documentation = "https://meta-pytorch.org/spmd_types/"
|
|
39
|
-
Repository = "https://github.com/meta-pytorch/spmd_types"
|
|
40
|
-
Issues = "https://github.com/meta-pytorch/spmd_types/issues"
|
|
41
|
-
|
|
42
|
-
[tool.setuptools.packages.find]
|
|
43
|
-
include = ["spmd_types*"]
|
|
44
|
-
|
|
45
|
-
[tool.setuptools.package-data]
|
|
46
|
-
spmd_types = ["py.typed"]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
[tool.ruff]
|
|
50
|
-
line-length = 88
|
|
51
|
-
target-version = "py310"
|
|
52
|
-
|
|
53
|
-
[tool.ruff.lint]
|
|
54
|
-
select = ["E4", "E7", "E9", "F"]
|
|
55
|
-
|
|
56
|
-
[tool.ruff.format]
|
|
57
|
-
exclude = ["*.md"]
|
|
58
|
-
quote-style = "double"
|
|
59
|
-
|
|
60
|
-
[tool.pytest.ini_options]
|
|
61
|
-
testpaths = ["tests"]
|
|
62
|
-
python_files = ["*_test.py"]
|
|
63
|
-
|
|
64
|
-
[tool.test-selector.extra-deps]
|
|
65
|
-
|
|
66
|
-
# BEGIN GENERATED buck-manual-deps -- do not edit by hand
|
|
67
|
-
# Regenerate: export_buck_manual_deps.py
|
|
68
|
-
"spmd_types/__init__.py" = ["../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_artifacts.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_artifacts_v22.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_audio_encoder_r6_i11_v22.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_conditioner_calibration_v21.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_ctts_pipeline_r6_i11_v22.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_recipe_r5_v21.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r5.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r6_i11_v22.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_sampling_r6_i11_v22_gb300.py", "../../llama4x/projects/experimental/rtai_avatar/pumpkin/sythetic_data/t2av/conversation_landscape_style_r5_v21.py", "../ops/interfaces/attn/triton_attention_fp32.py", "../ops/interfaces/gemm/gemm.py"]
|
|
69
|
-
# END GENERATED buck-manual-deps
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|