torchx-nightly 2025.7.25__py3-none-any.whl → 2025.7.26__py3-none-any.whl
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.
Potentially problematic release.
This version of torchx-nightly might be problematic. Click here for more details.
- torchx/runner/config.py +8 -8
- torchx/specs/api.py +61 -23
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/METADATA +1 -1
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/RECORD +8 -8
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/LICENSE +0 -0
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/WHEEL +0 -0
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/entry_points.txt +0 -0
- {torchx_nightly-2025.7.25.dist-info → torchx_nightly-2025.7.26.dist-info}/top_level.txt +0 -0
torchx/runner/config.py
CHANGED
|
@@ -278,14 +278,14 @@ def dump(
|
|
|
278
278
|
continue
|
|
279
279
|
|
|
280
280
|
# serialize list elements with `;` delimiter (consistent with torchx cli)
|
|
281
|
-
if opt.
|
|
281
|
+
if opt.is_type_list_of_str:
|
|
282
282
|
# deal with empty or None default lists
|
|
283
283
|
if opt.default:
|
|
284
284
|
# pyre-ignore[6] opt.default type checked already as List[str]
|
|
285
285
|
val = ";".join(opt.default)
|
|
286
286
|
else:
|
|
287
287
|
val = _NONE
|
|
288
|
-
elif opt.
|
|
288
|
+
elif opt.is_type_dict_of_str:
|
|
289
289
|
# deal with empty or None default lists
|
|
290
290
|
if opt.default:
|
|
291
291
|
# pyre-ignore[16] opt.default type checked already as Dict[str, str]
|
|
@@ -536,26 +536,26 @@ def load(scheduler: str, f: TextIO, cfg: Dict[str, CfgVal]) -> None:
|
|
|
536
536
|
# this also handles empty or None lists
|
|
537
537
|
cfg[name] = None
|
|
538
538
|
else:
|
|
539
|
-
|
|
539
|
+
opt = runopts.get(name)
|
|
540
540
|
|
|
541
|
-
if
|
|
541
|
+
if opt is None:
|
|
542
542
|
log.warning(
|
|
543
543
|
f"`{name} = {value}` was declared in the [{section}] section "
|
|
544
544
|
f" of the config file but is not a runopt of `{scheduler}` scheduler."
|
|
545
545
|
f" Remove the entry from the config file to no longer see this warning"
|
|
546
546
|
)
|
|
547
547
|
else:
|
|
548
|
-
if
|
|
548
|
+
if opt.opt_type is bool:
|
|
549
549
|
# need to handle bool specially since str -> bool is based on
|
|
550
550
|
# str emptiness not value (e.g. bool("False") == True)
|
|
551
551
|
cfg[name] = config.getboolean(section, name)
|
|
552
|
-
elif
|
|
552
|
+
elif opt.is_type_list_of_str:
|
|
553
553
|
cfg[name] = value.split(";")
|
|
554
|
-
elif
|
|
554
|
+
elif opt.is_type_dict_of_str:
|
|
555
555
|
cfg[name] = {
|
|
556
556
|
s.split(":", 1)[0]: s.split(":", 1)[1]
|
|
557
557
|
for s in value.replace(",", ";").split(";")
|
|
558
558
|
}
|
|
559
559
|
else:
|
|
560
560
|
# pyre-ignore[29]
|
|
561
|
-
cfg[name] =
|
|
561
|
+
cfg[name] = opt.opt_type(value)
|
torchx/specs/api.py
CHANGED
|
@@ -789,6 +789,60 @@ class runopt:
|
|
|
789
789
|
is_required: bool
|
|
790
790
|
help: str
|
|
791
791
|
|
|
792
|
+
@property
|
|
793
|
+
def is_type_list_of_str(self) -> bool:
|
|
794
|
+
"""
|
|
795
|
+
Checks if the option type is a list of strings.
|
|
796
|
+
|
|
797
|
+
Returns:
|
|
798
|
+
bool: True if the option type is either List[str] or list[str], False otherwise.
|
|
799
|
+
"""
|
|
800
|
+
return self.opt_type in (List[str], list[str])
|
|
801
|
+
|
|
802
|
+
@property
|
|
803
|
+
def is_type_dict_of_str(self) -> bool:
|
|
804
|
+
"""
|
|
805
|
+
Checks if the option type is a dict of string keys to string values.
|
|
806
|
+
|
|
807
|
+
Returns:
|
|
808
|
+
bool: True if the option type is either Dict[str, str] or dict[str, str], False otherwise.
|
|
809
|
+
"""
|
|
810
|
+
return self.opt_type in (Dict[str, str], dict[str, str])
|
|
811
|
+
|
|
812
|
+
def cast_to_type(self, value: str) -> CfgVal:
|
|
813
|
+
"""Casts the given `value` (in its string representation) to the type of this run option.
|
|
814
|
+
Below are the cast rules for each option type and value literal:
|
|
815
|
+
|
|
816
|
+
1. opt_type=str, value="foo" -> "foo"
|
|
817
|
+
1. opt_type=bool, value="True"/"False" -> True/False
|
|
818
|
+
1. opt_type=int, value="1" -> 1
|
|
819
|
+
1. opt_type=float, value="1.1" -> 1.1
|
|
820
|
+
1. opt_type=list[str]/List[str], value="a,b,c" or value="a;b;c" -> ["a", "b", "c"]
|
|
821
|
+
1. opt_type=dict[str,str]/Dict[str,str],
|
|
822
|
+
value="key1:val1,key2:val2" or value="key1:val1;key2:val2" -> {"key1": "val1", "key2": "val2"}
|
|
823
|
+
|
|
824
|
+
NOTE: dict parsing uses ":" as the kv separator (rather than the standard "=") because "=" is used
|
|
825
|
+
at the top-level cfg to parse runopts (notice the plural) from the CLI. Originally torchx only supported
|
|
826
|
+
primitives and list[str] as CfgVal but dict[str,str] was added in https://github.com/pytorch/torchx/pull/855
|
|
827
|
+
"""
|
|
828
|
+
|
|
829
|
+
if self.opt_type is None:
|
|
830
|
+
raise ValueError("runopt's opt_type cannot be `None`")
|
|
831
|
+
elif self.opt_type == bool:
|
|
832
|
+
return value.lower() == "true"
|
|
833
|
+
elif self.opt_type in (List[str], list[str]):
|
|
834
|
+
# lists may be ; or , delimited
|
|
835
|
+
# also deal with trailing "," by removing empty strings
|
|
836
|
+
return [v for v in value.replace(";", ",").split(",") if v]
|
|
837
|
+
elif self.opt_type in (Dict[str, str], dict[str, str]):
|
|
838
|
+
return {
|
|
839
|
+
s.split(":", 1)[0]: s.split(":", 1)[1]
|
|
840
|
+
for s in value.replace(";", ",").split(",")
|
|
841
|
+
}
|
|
842
|
+
else:
|
|
843
|
+
assert self.opt_type in (str, int, float)
|
|
844
|
+
return self.opt_type(value)
|
|
845
|
+
|
|
792
846
|
|
|
793
847
|
class runopts:
|
|
794
848
|
"""
|
|
@@ -948,27 +1002,11 @@ class runopts:
|
|
|
948
1002
|
|
|
949
1003
|
"""
|
|
950
1004
|
|
|
951
|
-
def _cast_to_type(value: str, opt_type: Type[CfgVal]) -> CfgVal:
|
|
952
|
-
if opt_type == bool:
|
|
953
|
-
return value.lower() == "true"
|
|
954
|
-
elif opt_type in (List[str], list[str]):
|
|
955
|
-
# lists may be ; or , delimited
|
|
956
|
-
# also deal with trailing "," by removing empty strings
|
|
957
|
-
return [v for v in value.replace(";", ",").split(",") if v]
|
|
958
|
-
elif opt_type in (Dict[str, str], dict[str, str]):
|
|
959
|
-
return {
|
|
960
|
-
s.split(":", 1)[0]: s.split(":", 1)[1]
|
|
961
|
-
for s in value.replace(";", ",").split(",")
|
|
962
|
-
}
|
|
963
|
-
else:
|
|
964
|
-
# pyre-ignore[19, 6] type won't be dict here as we handled it above
|
|
965
|
-
return opt_type(value)
|
|
966
|
-
|
|
967
1005
|
cfg: Dict[str, CfgVal] = {}
|
|
968
1006
|
for key, val in to_dict(cfg_str).items():
|
|
969
|
-
|
|
970
|
-
if
|
|
971
|
-
cfg[key] =
|
|
1007
|
+
opt = self.get(key)
|
|
1008
|
+
if opt:
|
|
1009
|
+
cfg[key] = opt.cast_to_type(val)
|
|
972
1010
|
else:
|
|
973
1011
|
logger.warning(
|
|
974
1012
|
f"{YELLOW_BOLD}Unknown run option passed to scheduler: {key}={val}{RESET}"
|
|
@@ -982,16 +1020,16 @@ class runopts:
|
|
|
982
1020
|
cfg: Dict[str, CfgVal] = {}
|
|
983
1021
|
cfg_dict = json.loads(json_repr)
|
|
984
1022
|
for key, val in cfg_dict.items():
|
|
985
|
-
|
|
986
|
-
if
|
|
1023
|
+
opt = self.get(key)
|
|
1024
|
+
if opt:
|
|
987
1025
|
# Optional runopt cfg values default their value to None,
|
|
988
1026
|
# but use `_type` to specify their type when provided.
|
|
989
1027
|
# Make sure not to treat None's as lists/dictionaries
|
|
990
1028
|
if val is None:
|
|
991
1029
|
cfg[key] = val
|
|
992
|
-
elif
|
|
1030
|
+
elif opt.is_type_list_of_str:
|
|
993
1031
|
cfg[key] = [str(v) for v in val]
|
|
994
|
-
elif
|
|
1032
|
+
elif opt.is_type_dict_of_str:
|
|
995
1033
|
cfg[key] = {str(k): str(v) for k, v in val.items()}
|
|
996
1034
|
else:
|
|
997
1035
|
cfg[key] = val
|
|
@@ -57,7 +57,7 @@ torchx/pipelines/kfp/adapter.py,sha256=5GeHULjb1kxG6wJtYVLpNkgdzUi4iYEaR42VFOwT6
|
|
|
57
57
|
torchx/pipelines/kfp/version.py,sha256=mYBxd6bm4MeR34D--xo-JLQ9wHeAl_ZQLwbItCf9tr0,539
|
|
58
58
|
torchx/runner/__init__.py,sha256=x8Sz7s_tLxPgJgvWIhK4ju9BNZU61uBFywGwDY6CqJs,315
|
|
59
59
|
torchx/runner/api.py,sha256=SQPwc_gar6o1qCBfjvG3XS4tQ6qcsNwUPuQTjJ6thXM,30085
|
|
60
|
-
torchx/runner/config.py,sha256=
|
|
60
|
+
torchx/runner/config.py,sha256=CBuYQCBj52fs4NclxJbdx5xtDdgNnfDd7XSdHPE1IGo,18267
|
|
61
61
|
torchx/runner/events/__init__.py,sha256=1_y0bojXl3FL0zlAj7BI4Dg5cXKXUmaa2jZbVH0EDUA,5268
|
|
62
62
|
torchx/runner/events/api.py,sha256=pPLfowWTXtN_XcrEDNI45pE6Ijvdc_Gdxq76RduqgGE,2664
|
|
63
63
|
torchx/runner/events/handlers.py,sha256=ThHCIJW21BfBgB7b6ftyjASJmD1KdizpjuTtsyqnvJs,522
|
|
@@ -83,7 +83,7 @@ torchx/schedulers/ray/__init__.py,sha256=fE0IHi1JJpxsNVBNzWNee2thrNXFFRhY94c80Rx
|
|
|
83
83
|
torchx/schedulers/ray/ray_common.py,sha256=pyNYFvTKVwdjDAeCBNbPwAWwVNmlLOJWExfn90XY8u8,610
|
|
84
84
|
torchx/schedulers/ray/ray_driver.py,sha256=RdaCLfth16ky-5PDVOWRe_RuheWJu9xufWux2F9T7iw,12302
|
|
85
85
|
torchx/specs/__init__.py,sha256=c2ALDbqHIhNBhrYxwXXURRwu1Rg5jcwukWF8emEO1Bk,6347
|
|
86
|
-
torchx/specs/api.py,sha256=
|
|
86
|
+
torchx/specs/api.py,sha256=wkhHOxeWH_tFO3npKqPhNg4VX2NH5gPIFEylkPBo3AU,41315
|
|
87
87
|
torchx/specs/builders.py,sha256=f5Yy8KoL2OgPUiqJRkZ4E6lboq5Srkh5mD17F0EBdeg,10506
|
|
88
88
|
torchx/specs/file_linter.py,sha256=QCwob5STTBuy8RsxaevTI-Dk6R8siDJn81LyaOwazes,12333
|
|
89
89
|
torchx/specs/finder.py,sha256=lMCS1hUR-x7j4sAjfJZnKFeS1RlkFTeJtit4EL_ErIo,18182
|
|
@@ -115,9 +115,9 @@ torchx/workspace/__init__.py,sha256=FqN8AN4VhR1C_SBY10MggQvNZmyanbbuPuE-JCjkyUY,
|
|
|
115
115
|
torchx/workspace/api.py,sha256=PtDkGTC5lX03pRoYpuMz2KCmM1ZOycRP1UknqvNb97Y,6341
|
|
116
116
|
torchx/workspace/dir_workspace.py,sha256=npNW_IjUZm_yS5r-8hrRkH46ndDd9a_eApT64m1S1T4,2268
|
|
117
117
|
torchx/workspace/docker_workspace.py,sha256=PFu2KQNVC-0p2aKJ-W_BKA9ZOmXdCY2ABEkCExp3udQ,10269
|
|
118
|
-
torchx_nightly-2025.7.
|
|
119
|
-
torchx_nightly-2025.7.
|
|
120
|
-
torchx_nightly-2025.7.
|
|
121
|
-
torchx_nightly-2025.7.
|
|
122
|
-
torchx_nightly-2025.7.
|
|
123
|
-
torchx_nightly-2025.7.
|
|
118
|
+
torchx_nightly-2025.7.26.dist-info/LICENSE,sha256=WVHfXhFC0Ia8LTKt_nJVYobdqTJVg_4J3Crrfm2A8KQ,1721
|
|
119
|
+
torchx_nightly-2025.7.26.dist-info/METADATA,sha256=vNr_1yuJ5mfSErMVZsOFSczuLwZ7sr8ALbH7ubOMPro,6104
|
|
120
|
+
torchx_nightly-2025.7.26.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
121
|
+
torchx_nightly-2025.7.26.dist-info/entry_points.txt,sha256=T328AMXeKI3JZnnxfkEew2ZcMN1oQDtkXjMz7lkV-P4,169
|
|
122
|
+
torchx_nightly-2025.7.26.dist-info/top_level.txt,sha256=pxew3bc2gsiViS0zADs0jb6kC5v8o_Yy_85fhHj_J1A,7
|
|
123
|
+
torchx_nightly-2025.7.26.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|