torchx-nightly 2025.9.2__py3-none-any.whl → 2025.9.4__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/cli/cmd_run.py +175 -20
- torchx/runner/api.py +7 -15
- torchx/specs/__init__.py +3 -0
- torchx/specs/builders.py +5 -1
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/METADATA +1 -1
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/RECORD +10 -10
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/LICENSE +0 -0
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/WHEEL +0 -0
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/entry_points.txt +0 -0
- {torchx_nightly-2025.9.2.dist-info → torchx_nightly-2025.9.4.dist-info}/top_level.txt +0 -0
torchx/cli/cmd_run.py
CHANGED
|
@@ -7,16 +7,17 @@
|
|
|
7
7
|
# pyre-strict
|
|
8
8
|
|
|
9
9
|
import argparse
|
|
10
|
+
import json
|
|
10
11
|
import logging
|
|
11
12
|
import os
|
|
12
13
|
import sys
|
|
13
14
|
import threading
|
|
14
15
|
from collections import Counter
|
|
15
|
-
from dataclasses import asdict
|
|
16
|
+
from dataclasses import asdict, dataclass, field, fields, MISSING as DATACLASS_MISSING
|
|
16
17
|
from itertools import groupby
|
|
17
18
|
from pathlib import Path
|
|
18
19
|
from pprint import pformat
|
|
19
|
-
from typing import Dict, List, Optional, Tuple
|
|
20
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
20
21
|
|
|
21
22
|
import torchx.specs as specs
|
|
22
23
|
from torchx.cli.argparse_util import ArgOnceAction, torchxconfig_run
|
|
@@ -25,6 +26,7 @@ from torchx.cli.cmd_log import get_logs
|
|
|
25
26
|
from torchx.runner import config, get_runner, Runner
|
|
26
27
|
from torchx.runner.config import load_sections
|
|
27
28
|
from torchx.schedulers import get_default_scheduler_name, get_scheduler_factories
|
|
29
|
+
from torchx.specs import CfgVal
|
|
28
30
|
from torchx.specs.finder import (
|
|
29
31
|
_Component,
|
|
30
32
|
ComponentNotFoundException,
|
|
@@ -40,10 +42,81 @@ MISSING_COMPONENT_ERROR_MSG = (
|
|
|
40
42
|
"missing component name, either provide it from the CLI or in .torchxconfig"
|
|
41
43
|
)
|
|
42
44
|
|
|
45
|
+
LOCAL_SCHEDULER_WARNING_MSG = (
|
|
46
|
+
"`local` scheduler is deprecated and will be"
|
|
47
|
+
" removed in the near future,"
|
|
48
|
+
" please use other variants of the local scheduler"
|
|
49
|
+
" (e.g. `local_cwd`)"
|
|
50
|
+
)
|
|
43
51
|
|
|
44
52
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
45
53
|
|
|
46
54
|
|
|
55
|
+
@dataclass
|
|
56
|
+
class TorchXRunArgs:
|
|
57
|
+
component_name: str
|
|
58
|
+
scheduler: str
|
|
59
|
+
scheduler_args: Dict[str, Any]
|
|
60
|
+
scheduler_cfg: Dict[str, CfgVal] = field(default_factory=dict)
|
|
61
|
+
dryrun: bool = False
|
|
62
|
+
wait: bool = False
|
|
63
|
+
log: bool = False
|
|
64
|
+
workspace: str = ""
|
|
65
|
+
parent_run_id: Optional[str] = None
|
|
66
|
+
tee_logs: bool = False
|
|
67
|
+
component_args: Dict[str, Any] = field(default_factory=dict)
|
|
68
|
+
component_args_str: List[str] = field(default_factory=list)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def torchx_run_args_from_json(json_data: Dict[str, Any]) -> TorchXRunArgs:
|
|
72
|
+
all_fields = [f.name for f in fields(TorchXRunArgs)]
|
|
73
|
+
required_fields = {
|
|
74
|
+
f.name
|
|
75
|
+
for f in fields(TorchXRunArgs)
|
|
76
|
+
if f.default is DATACLASS_MISSING and f.default_factory is DATACLASS_MISSING
|
|
77
|
+
}
|
|
78
|
+
missing_fields = required_fields - json_data.keys()
|
|
79
|
+
if missing_fields:
|
|
80
|
+
raise ValueError(
|
|
81
|
+
f"The following required fields are missing: {', '.join(missing_fields)}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Fail if there are fields that aren't part of the run command
|
|
85
|
+
filtered_json_data = {k: v for k, v in json_data.items() if k in all_fields}
|
|
86
|
+
extra_fields = set(json_data.keys()) - set(all_fields)
|
|
87
|
+
if extra_fields:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"The following fields are not part of the run command: {', '.join(extra_fields)}.",
|
|
90
|
+
"Please check your JSON and try launching again.",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
torchx_args = TorchXRunArgs(**filtered_json_data)
|
|
94
|
+
if torchx_args.workspace == "":
|
|
95
|
+
torchx_args.workspace = f"file://{Path.cwd()}"
|
|
96
|
+
return torchx_args
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def torchx_run_args_from_argparse(
|
|
100
|
+
args: argparse.Namespace,
|
|
101
|
+
component_name: str,
|
|
102
|
+
component_args: List[str],
|
|
103
|
+
scheduler_cfg: Dict[str, CfgVal],
|
|
104
|
+
) -> TorchXRunArgs:
|
|
105
|
+
return TorchXRunArgs(
|
|
106
|
+
component_name=component_name,
|
|
107
|
+
scheduler=args.scheduler,
|
|
108
|
+
scheduler_args={},
|
|
109
|
+
scheduler_cfg=scheduler_cfg,
|
|
110
|
+
dryrun=args.dryrun,
|
|
111
|
+
wait=args.wait,
|
|
112
|
+
log=args.log,
|
|
113
|
+
workspace=args.workspace,
|
|
114
|
+
parent_run_id=args.parent_run_id,
|
|
115
|
+
tee_logs=args.tee_logs,
|
|
116
|
+
component_args_str=component_args,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
47
120
|
def _parse_component_name_and_args(
|
|
48
121
|
component_name_and_args: List[str],
|
|
49
122
|
subparser: argparse.ArgumentParser,
|
|
@@ -193,35 +266,35 @@ class CmdRun(SubCommand):
|
|
|
193
266
|
default=False,
|
|
194
267
|
help="Add additional prefix to log lines to indicate which replica is printing the log",
|
|
195
268
|
)
|
|
269
|
+
subparser.add_argument(
|
|
270
|
+
"--stdin",
|
|
271
|
+
action="store_true",
|
|
272
|
+
default=False,
|
|
273
|
+
help="Read JSON input from stdin to parse into torchx run args and run the component.",
|
|
274
|
+
)
|
|
196
275
|
subparser.add_argument(
|
|
197
276
|
"component_name_and_args",
|
|
198
277
|
nargs=argparse.REMAINDER,
|
|
199
278
|
)
|
|
200
279
|
|
|
201
|
-
def
|
|
280
|
+
def _run_inner(self, runner: Runner, args: TorchXRunArgs) -> None:
|
|
202
281
|
if args.scheduler == "local":
|
|
203
|
-
logger.warning(
|
|
204
|
-
"`local` scheduler is deprecated and will be"
|
|
205
|
-
" removed in the near future,"
|
|
206
|
-
" please use other variants of the local scheduler"
|
|
207
|
-
" (e.g. `local_cwd`)"
|
|
208
|
-
)
|
|
282
|
+
logger.warning(LOCAL_SCHEDULER_WARNING_MSG)
|
|
209
283
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
args.
|
|
215
|
-
none_throws(self._subparser),
|
|
284
|
+
config.apply(scheduler=args.scheduler, cfg=args.scheduler_cfg)
|
|
285
|
+
component_args = (
|
|
286
|
+
args.component_args_str
|
|
287
|
+
if args.component_args_str != []
|
|
288
|
+
else args.component_args
|
|
216
289
|
)
|
|
217
290
|
try:
|
|
218
291
|
if args.dryrun:
|
|
219
292
|
dryrun_info = runner.dryrun_component(
|
|
220
|
-
|
|
293
|
+
args.component_name,
|
|
221
294
|
component_args,
|
|
222
295
|
args.scheduler,
|
|
223
296
|
workspace=args.workspace,
|
|
224
|
-
cfg=
|
|
297
|
+
cfg=args.scheduler_cfg,
|
|
225
298
|
parent_run_id=args.parent_run_id,
|
|
226
299
|
)
|
|
227
300
|
print(
|
|
@@ -232,11 +305,11 @@ class CmdRun(SubCommand):
|
|
|
232
305
|
print("\n=== SCHEDULER REQUEST ===\n" f"{dryrun_info}")
|
|
233
306
|
else:
|
|
234
307
|
app_handle = runner.run_component(
|
|
235
|
-
|
|
308
|
+
args.component_name,
|
|
236
309
|
component_args,
|
|
237
310
|
args.scheduler,
|
|
238
311
|
workspace=args.workspace,
|
|
239
|
-
cfg=
|
|
312
|
+
cfg=args.scheduler_cfg,
|
|
240
313
|
parent_run_id=args.parent_run_id,
|
|
241
314
|
)
|
|
242
315
|
# DO NOT delete this line. It is used by slurm tests to retrieve the app id
|
|
@@ -257,7 +330,9 @@ class CmdRun(SubCommand):
|
|
|
257
330
|
)
|
|
258
331
|
|
|
259
332
|
except (ComponentValidationException, ComponentNotFoundException) as e:
|
|
260
|
-
error_msg =
|
|
333
|
+
error_msg = (
|
|
334
|
+
f"\nFailed to run component `{args.component_name}` got errors: \n {e}"
|
|
335
|
+
)
|
|
261
336
|
logger.error(error_msg)
|
|
262
337
|
sys.exit(1)
|
|
263
338
|
except specs.InvalidRunConfigException as e:
|
|
@@ -272,6 +347,86 @@ class CmdRun(SubCommand):
|
|
|
272
347
|
print(error_msg % (e, args.scheduler, args.scheduler), file=sys.stderr)
|
|
273
348
|
sys.exit(1)
|
|
274
349
|
|
|
350
|
+
def _run_from_cli_args(self, runner: Runner, args: argparse.Namespace) -> None:
|
|
351
|
+
scheduler_opts = runner.scheduler_run_opts(args.scheduler)
|
|
352
|
+
cfg = scheduler_opts.cfg_from_str(args.scheduler_args)
|
|
353
|
+
|
|
354
|
+
component, component_args = _parse_component_name_and_args(
|
|
355
|
+
args.component_name_and_args,
|
|
356
|
+
none_throws(self._subparser),
|
|
357
|
+
)
|
|
358
|
+
torchx_run_args = torchx_run_args_from_argparse(
|
|
359
|
+
args, component, component_args, cfg
|
|
360
|
+
)
|
|
361
|
+
self._run_inner(runner, torchx_run_args)
|
|
362
|
+
|
|
363
|
+
def _run_from_stdin_args(self, runner: Runner, stdin_data: Dict[str, Any]) -> None:
|
|
364
|
+
torchx_run_args = torchx_run_args_from_json(stdin_data)
|
|
365
|
+
scheduler_opts = runner.scheduler_run_opts(torchx_run_args.scheduler)
|
|
366
|
+
cfg = scheduler_opts.cfg_from_json_repr(
|
|
367
|
+
json.dumps(torchx_run_args.scheduler_args)
|
|
368
|
+
)
|
|
369
|
+
torchx_run_args.scheduler_cfg = cfg
|
|
370
|
+
self._run_inner(runner, torchx_run_args)
|
|
371
|
+
|
|
372
|
+
def torchx_json_from_stdin(self) -> Dict[str, Any]:
|
|
373
|
+
try:
|
|
374
|
+
stdin_data_json = json.load(sys.stdin)
|
|
375
|
+
if not isinstance(stdin_data_json, dict):
|
|
376
|
+
logger.error(
|
|
377
|
+
"Invalid JSON input for `torchx run` command. Expected a dictionary."
|
|
378
|
+
)
|
|
379
|
+
sys.exit(1)
|
|
380
|
+
return stdin_data_json
|
|
381
|
+
except (json.JSONDecodeError, EOFError):
|
|
382
|
+
logger.error(
|
|
383
|
+
"Unable to parse JSON input for `torchx run` command, please make sure it's a valid JSON input."
|
|
384
|
+
)
|
|
385
|
+
sys.exit(1)
|
|
386
|
+
|
|
387
|
+
def verify_no_extra_args(self, args: argparse.Namespace) -> None:
|
|
388
|
+
"""
|
|
389
|
+
Verifies that only --stdin was provided when using stdin mode.
|
|
390
|
+
"""
|
|
391
|
+
if not args.stdin:
|
|
392
|
+
return
|
|
393
|
+
|
|
394
|
+
subparser = none_throws(self._subparser)
|
|
395
|
+
conflicting_args = []
|
|
396
|
+
|
|
397
|
+
# Check each argument against its default value
|
|
398
|
+
for action in subparser._actions:
|
|
399
|
+
if action.dest == "stdin": # Skip stdin itself
|
|
400
|
+
continue
|
|
401
|
+
if action.dest == "help": # Skip help
|
|
402
|
+
continue
|
|
403
|
+
|
|
404
|
+
current_value = getattr(args, action.dest, None)
|
|
405
|
+
default_value = action.default
|
|
406
|
+
|
|
407
|
+
# For arguments that differ from default
|
|
408
|
+
if current_value != default_value:
|
|
409
|
+
# Handle special cases where non-default doesn't mean explicitly set
|
|
410
|
+
if action.dest == "component_name_and_args" and current_value == []:
|
|
411
|
+
continue # Empty list is still default
|
|
412
|
+
print(f"*********\n {default_value} = {current_value}")
|
|
413
|
+
conflicting_args.append(f"--{action.dest.replace('_', '-')}")
|
|
414
|
+
|
|
415
|
+
if conflicting_args:
|
|
416
|
+
subparser.error(
|
|
417
|
+
f"Cannot specify {', '.join(conflicting_args)} when using --stdin. "
|
|
418
|
+
"All configuration should be provided in JSON input."
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
def _run(self, runner: Runner, args: argparse.Namespace) -> None:
|
|
422
|
+
# Verify no conflicting arguments when using to loop over the stdin
|
|
423
|
+
self.verify_no_extra_args(args)
|
|
424
|
+
if args.stdin:
|
|
425
|
+
stdin_data_json = self.torchx_json_from_stdin()
|
|
426
|
+
self._run_from_stdin_args(runner, stdin_data_json)
|
|
427
|
+
else:
|
|
428
|
+
self._run_from_cli_args(runner, args)
|
|
429
|
+
|
|
275
430
|
def run(self, args: argparse.Namespace) -> None:
|
|
276
431
|
os.environ["TORCHX_CONTEXT_NAME"] = os.getenv("TORCHX_CONTEXT_NAME", "cli_run")
|
|
277
432
|
component_defaults = load_sections(prefix="component")
|
torchx/runner/api.py
CHANGED
|
@@ -25,6 +25,7 @@ from typing import (
|
|
|
25
25
|
Type,
|
|
26
26
|
TYPE_CHECKING,
|
|
27
27
|
TypeVar,
|
|
28
|
+
Union,
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
from torchx.runner.events import log_event
|
|
@@ -164,22 +165,10 @@ class Runner:
|
|
|
164
165
|
for scheduler in self._scheduler_instances.values():
|
|
165
166
|
scheduler.close()
|
|
166
167
|
|
|
167
|
-
def build_standalone_workspace(
|
|
168
|
-
self,
|
|
169
|
-
workspace_builder: WorkspaceBuilder[S, T],
|
|
170
|
-
sync: bool = True,
|
|
171
|
-
) -> PkgInfo[S]:
|
|
172
|
-
"""
|
|
173
|
-
Build a standalone workspace for the given role.
|
|
174
|
-
This method is used to build a workspace for a role independent of the scheduler and
|
|
175
|
-
also enables asynchronous workspace building using the Role overrides.
|
|
176
|
-
"""
|
|
177
|
-
return workspace_builder.build_workspace(sync)
|
|
178
|
-
|
|
179
168
|
def run_component(
|
|
180
169
|
self,
|
|
181
170
|
component: str,
|
|
182
|
-
component_args:
|
|
171
|
+
component_args: Union[list[str], dict[str, Any]],
|
|
183
172
|
scheduler: str,
|
|
184
173
|
cfg: Optional[Mapping[str, CfgVal]] = None,
|
|
185
174
|
workspace: Optional[str] = None,
|
|
@@ -238,7 +227,7 @@ class Runner:
|
|
|
238
227
|
def dryrun_component(
|
|
239
228
|
self,
|
|
240
229
|
component: str,
|
|
241
|
-
component_args:
|
|
230
|
+
component_args: Union[list[str], dict[str, Any]],
|
|
242
231
|
scheduler: str,
|
|
243
232
|
cfg: Optional[Mapping[str, CfgVal]] = None,
|
|
244
233
|
workspace: Optional[str] = None,
|
|
@@ -249,10 +238,13 @@ class Runner:
|
|
|
249
238
|
component, but just returns what "would" have run.
|
|
250
239
|
"""
|
|
251
240
|
component_def = get_component(component)
|
|
241
|
+
args_from_cli = component_args if isinstance(component_args, list) else []
|
|
242
|
+
args_from_json = component_args if isinstance(component_args, dict) else {}
|
|
252
243
|
app = materialize_appdef(
|
|
253
244
|
component_def.fn,
|
|
254
|
-
|
|
245
|
+
args_from_cli,
|
|
255
246
|
self._component_defaults.get(component, None),
|
|
247
|
+
args_from_json,
|
|
256
248
|
)
|
|
257
249
|
return self.dryrun(
|
|
258
250
|
app,
|
torchx/specs/__init__.py
CHANGED
torchx/specs/builders.py
CHANGED
|
@@ -213,7 +213,11 @@ def component_args_from_str(
|
|
|
213
213
|
arg_value = getattr(parsed_args, param_name)
|
|
214
214
|
parameter_type = parameter.annotation
|
|
215
215
|
parameter_type = decode_optional(parameter_type)
|
|
216
|
-
|
|
216
|
+
if (
|
|
217
|
+
parameter_type != arg_value.__class__
|
|
218
|
+
and parameter.kind != inspect.Parameter.VAR_POSITIONAL
|
|
219
|
+
):
|
|
220
|
+
arg_value = decode(arg_value, parameter_type)
|
|
217
221
|
if parameter.kind == inspect.Parameter.VAR_POSITIONAL:
|
|
218
222
|
var_args = arg_value
|
|
219
223
|
elif parameter.kind == inspect.Parameter.KEYWORD_ONLY:
|
|
@@ -16,7 +16,7 @@ torchx/cli/cmd_configure.py,sha256=1kTv0qbsbV44So74plAySwWu56pQrqjhfW_kbfdC3Rw,1
|
|
|
16
16
|
torchx/cli/cmd_describe.py,sha256=E5disbHoKTsqYKp2s3DaFW9GDLCCOgdOc3pQoHKoyCs,1283
|
|
17
17
|
torchx/cli/cmd_list.py,sha256=4Y1ZOq-kqJbztoBt56hAW_InJEaJuDAjpKWgMhBw4II,1507
|
|
18
18
|
torchx/cli/cmd_log.py,sha256=v-EZYUDOcG95rEgTnrsmPJMUyxM9Mk8YFAJtUxtgViE,5475
|
|
19
|
-
torchx/cli/cmd_run.py,sha256=
|
|
19
|
+
torchx/cli/cmd_run.py,sha256=BtLl-FBVnf1B5VjyCMFgJrL20-PQN9k9akN6Oa3RGgg,18126
|
|
20
20
|
torchx/cli/cmd_runopts.py,sha256=NWZiP8XpQjfTDJgays2c6MgL_8wxFoeDge6NstaZdKk,1302
|
|
21
21
|
torchx/cli/cmd_status.py,sha256=22IAEmKs0qkG6kJi83u9dRX2Q-ntT7yehVx7FxtY-vQ,2114
|
|
22
22
|
torchx/cli/cmd_tracker.py,sha256=RfLxE4Cq1wfk7k051RtZ8RPJp0pEKSCa3KmTeRs3LF8,5218
|
|
@@ -56,7 +56,7 @@ torchx/pipelines/kfp/__init__.py,sha256=8iJ8lql_fxwuk9VCYSxXnX6tPL228fB5mDZpOs-k
|
|
|
56
56
|
torchx/pipelines/kfp/adapter.py,sha256=5GeHULjb1kxG6wJtYVLpNkgdzUi4iYEaR42VFOwT6fY,9045
|
|
57
57
|
torchx/pipelines/kfp/version.py,sha256=mYBxd6bm4MeR34D--xo-JLQ9wHeAl_ZQLwbItCf9tr0,539
|
|
58
58
|
torchx/runner/__init__.py,sha256=x8Sz7s_tLxPgJgvWIhK4ju9BNZU61uBFywGwDY6CqJs,315
|
|
59
|
-
torchx/runner/api.py,sha256=
|
|
59
|
+
torchx/runner/api.py,sha256=CJmTjoV2kB0FVqeE9B-bYaFyiMuQsZCY32kY13CIk6I,30559
|
|
60
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
|
|
@@ -82,9 +82,9 @@ torchx/schedulers/streams.py,sha256=8_SLezgnWgfv_zXUsJCUM34-h2dtv25NmZuxEwkzmxw,
|
|
|
82
82
|
torchx/schedulers/ray/__init__.py,sha256=fE0IHi1JJpxsNVBNzWNee2thrNXFFRhY94c80RxNSIE,231
|
|
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
|
-
torchx/specs/__init__.py,sha256=
|
|
85
|
+
torchx/specs/__init__.py,sha256=Gw_2actqR_oWFtxEkGXCxGk_yrWK5JDZzwysyyqmXao,6438
|
|
86
86
|
torchx/specs/api.py,sha256=wkhHOxeWH_tFO3npKqPhNg4VX2NH5gPIFEylkPBo3AU,41315
|
|
87
|
-
torchx/specs/builders.py,sha256=
|
|
87
|
+
torchx/specs/builders.py,sha256=aozVl4q3h0mY5DDJCY1M1CyLC9SW66KJy8JIih8bZJo,13810
|
|
88
88
|
torchx/specs/file_linter.py,sha256=QCwob5STTBuy8RsxaevTI-Dk6R8siDJn81LyaOwazes,12333
|
|
89
89
|
torchx/specs/finder.py,sha256=lMCS1hUR-x7j4sAjfJZnKFeS1RlkFTeJtit4EL_ErIo,18182
|
|
90
90
|
torchx/specs/named_resources_aws.py,sha256=ISjHtifRJqB8u7PeAMiyLyO_S0WCaZiK-CFF3qe6JDU,11415
|
|
@@ -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.9.
|
|
119
|
-
torchx_nightly-2025.9.
|
|
120
|
-
torchx_nightly-2025.9.
|
|
121
|
-
torchx_nightly-2025.9.
|
|
122
|
-
torchx_nightly-2025.9.
|
|
123
|
-
torchx_nightly-2025.9.
|
|
118
|
+
torchx_nightly-2025.9.4.dist-info/LICENSE,sha256=WVHfXhFC0Ia8LTKt_nJVYobdqTJVg_4J3Crrfm2A8KQ,1721
|
|
119
|
+
torchx_nightly-2025.9.4.dist-info/METADATA,sha256=JbjR1Xl4KB9UbvnpQyD7EXmVS9xI376IdmQh8L7Hdqc,6103
|
|
120
|
+
torchx_nightly-2025.9.4.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
121
|
+
torchx_nightly-2025.9.4.dist-info/entry_points.txt,sha256=T328AMXeKI3JZnnxfkEew2ZcMN1oQDtkXjMz7lkV-P4,169
|
|
122
|
+
torchx_nightly-2025.9.4.dist-info/top_level.txt,sha256=pxew3bc2gsiViS0zADs0jb6kC5v8o_Yy_85fhHj_J1A,7
|
|
123
|
+
torchx_nightly-2025.9.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|