nv-sflow 0.3.1__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.
Files changed (225) hide show
  1. nv_sflow-0.3.1.dist-info/METADATA +273 -0
  2. nv_sflow-0.3.1.dist-info/RECORD +225 -0
  3. nv_sflow-0.3.1.dist-info/WHEEL +5 -0
  4. nv_sflow-0.3.1.dist-info/entry_points.txt +2 -0
  5. nv_sflow-0.3.1.dist-info/licenses/LICENSE +176 -0
  6. nv_sflow-0.3.1.dist-info/top_level.txt +1 -0
  7. sflow/__init__.py +16 -0
  8. sflow/__main__.py +7 -0
  9. sflow/_version.py +21 -0
  10. sflow/app/__init__.py +6 -0
  11. sflow/app/assembly.py +1780 -0
  12. sflow/app/backend_lifecycle.py +284 -0
  13. sflow/app/monitor_cli.py +157 -0
  14. sflow/app/monitor_planner.py +780 -0
  15. sflow/app/resource_planner.py +1680 -0
  16. sflow/app/run_support.py +369 -0
  17. sflow/app/sflow.py +1532 -0
  18. sflow/app/task_context.py +224 -0
  19. sflow/cli/__init__.py +100 -0
  20. sflow/cli/_args.py +107 -0
  21. sflow/cli/batch.py +3579 -0
  22. sflow/cli/compose.py +616 -0
  23. sflow/cli/run.py +689 -0
  24. sflow/cli/sample.py +453 -0
  25. sflow/cli/skill.py +347 -0
  26. sflow/cli/upgrade.py +274 -0
  27. sflow/cli/visualize.py +181 -0
  28. sflow/config/__init__.py +6 -0
  29. sflow/config/loader.py +829 -0
  30. sflow/config/resolver.py +17 -0
  31. sflow/config/schema.py +1425 -0
  32. sflow/core/__init__.py +6 -0
  33. sflow/core/artifact.py +43 -0
  34. sflow/core/artifact_registry.py +131 -0
  35. sflow/core/backend.py +252 -0
  36. sflow/core/backend_registry.py +78 -0
  37. sflow/core/command.py +120 -0
  38. sflow/core/command_log.py +138 -0
  39. sflow/core/command_trace.py +361 -0
  40. sflow/core/compute_node.py +32 -0
  41. sflow/core/constraints.py +22 -0
  42. sflow/core/context.py +53 -0
  43. sflow/core/dag.py +397 -0
  44. sflow/core/execution_summary.py +1043 -0
  45. sflow/core/kubectl_config.py +133 -0
  46. sflow/core/launcher.py +395 -0
  47. sflow/core/log_offload.py +199 -0
  48. sflow/core/loop_watchdog.py +167 -0
  49. sflow/core/monitor.py +273 -0
  50. sflow/core/operator.py +228 -0
  51. sflow/core/operator_registry.py +139 -0
  52. sflow/core/orchestrator.py +1423 -0
  53. sflow/core/outputs.py +121 -0
  54. sflow/core/probe.py +205 -0
  55. sflow/core/probe_transport.py +95 -0
  56. sflow/core/replica.py +2 -0
  57. sflow/core/resource.py +9 -0
  58. sflow/core/results.py +668 -0
  59. sflow/core/state.py +67 -0
  60. sflow/core/storage.py +48 -0
  61. sflow/core/storage_registry.py +78 -0
  62. sflow/core/task.py +313 -0
  63. sflow/core/task_graph.py +68 -0
  64. sflow/core/uploads.py +558 -0
  65. sflow/core/variable.py +247 -0
  66. sflow/core/workflow.py +30 -0
  67. sflow/logging.py +287 -0
  68. sflow/monitoring/__init__.py +46 -0
  69. sflow/monitoring/hardware_monitor.py +326 -0
  70. sflow/monitoring/postprocess_monitor_timeline.py +2157 -0
  71. sflow/plugins/__init__.py +6 -0
  72. sflow/plugins/artifacts/__init__.py +19 -0
  73. sflow/plugins/artifacts/docker.py +36 -0
  74. sflow/plugins/artifacts/http.py +49 -0
  75. sflow/plugins/artifacts/huggingface.py +38 -0
  76. sflow/plugins/artifacts/local.py +133 -0
  77. sflow/plugins/backends/__init__.py +13 -0
  78. sflow/plugins/backends/docker.py +401 -0
  79. sflow/plugins/backends/kubernetes.py +3480 -0
  80. sflow/plugins/backends/local.py +145 -0
  81. sflow/plugins/backends/slurm.py +792 -0
  82. sflow/plugins/k8s/__init__.py +14 -0
  83. sflow/plugins/k8s/capabilities.py +116 -0
  84. sflow/plugins/k8s/lifecycle.py +1291 -0
  85. sflow/plugins/k8s/log_demux.py +201 -0
  86. sflow/plugins/k8s/mpi_bootstrap.py +852 -0
  87. sflow/plugins/k8s/mpi_lifecycle.py +134 -0
  88. sflow/plugins/k8s/probe.py +153 -0
  89. sflow/plugins/k8s/rdma.py +371 -0
  90. sflow/plugins/k8s/rdma_preamble.py +365 -0
  91. sflow/plugins/k8s/render.py +1077 -0
  92. sflow/plugins/k8s/shell.py +637 -0
  93. sflow/plugins/operators/__init__.py +31 -0
  94. sflow/plugins/operators/bash.py +72 -0
  95. sflow/plugins/operators/docker_run.py +694 -0
  96. sflow/plugins/operators/gpu_placement.sh +260 -0
  97. sflow/plugins/operators/k8s.py +34 -0
  98. sflow/plugins/operators/k8s_mpi.py +808 -0
  99. sflow/plugins/operators/k8s_operator.py +2703 -0
  100. sflow/plugins/operators/python.py +61 -0
  101. sflow/plugins/operators/srun.py +624 -0
  102. sflow/plugins/operators/ssh.py +68 -0
  103. sflow/plugins/probes/__init__.py +19 -0
  104. sflow/plugins/probes/http.py +94 -0
  105. sflow/plugins/probes/log_watch.py +197 -0
  106. sflow/plugins/probes/tcp_port.py +66 -0
  107. sflow/plugins/storage/__init__.py +16 -0
  108. sflow/plugins/storage/s3.py +194 -0
  109. sflow/resolution.py +1264 -0
  110. sflow/runtime_info.py +271 -0
  111. sflow/samples/__init__.py +81 -0
  112. sflow/samples/modular/backend_agnostic/README.md +156 -0
  113. sflow/samples/modular/backend_agnostic/backends/docker.yaml +75 -0
  114. sflow/samples/modular/backend_agnostic/backends/k8s.yaml +54 -0
  115. sflow/samples/modular/backend_agnostic/backends/k8s_mpi.yaml +63 -0
  116. sflow/samples/modular/backend_agnostic/backends/slurm.yaml +67 -0
  117. sflow/samples/modular/backend_agnostic/benchmark.yaml +61 -0
  118. sflow/samples/modular/backend_agnostic/workloads/dynamo_common.yaml +81 -0
  119. sflow/samples/modular/backend_agnostic/workloads/dynamo_sglang.yaml +55 -0
  120. sflow/samples/modular/backend_agnostic/workloads/dynamo_sglang_disagg.yaml +117 -0
  121. sflow/samples/modular/backend_agnostic/workloads/dynamo_trtllm.yaml +100 -0
  122. sflow/samples/modular/backend_agnostic/workloads/dynamo_trtllm_disagg.yaml +165 -0
  123. sflow/samples/modular/backend_agnostic/workloads/dynamo_vllm.yaml +56 -0
  124. sflow/samples/modular/backend_agnostic/workloads/dynamo_vllm_disagg.yaml +126 -0
  125. sflow/samples/modular/backend_agnostic/workloads/sglang_serve.yaml +53 -0
  126. sflow/samples/modular/backend_agnostic/workloads/trtllm_serve.yaml +66 -0
  127. sflow/samples/modular/backend_agnostic/workloads/vllm_serve.yaml +57 -0
  128. sflow/samples/modular/inference_x_v2/benchmark_aiperf.yaml +84 -0
  129. sflow/samples/modular/inference_x_v2/benchmark_infmax.yaml +79 -0
  130. sflow/samples/modular/inference_x_v2/bulk_input.csv +10 -0
  131. sflow/samples/modular/inference_x_v2/common_workflow.yaml +359 -0
  132. sflow/samples/modular/inference_x_v2/composed_recipes/sglang_agg_benchmark_aiperf_2n_008.yaml +370 -0
  133. sflow/samples/modular/inference_x_v2/composed_recipes/sglang_prefill_decode_benchmar_003.yaml +434 -0
  134. sflow/samples/modular/inference_x_v2/composed_recipes/sglang_prefill_decode_benchmar_004.yaml +435 -0
  135. sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_agg_benchmark_aiperf_1n_007.yaml +393 -0
  136. sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_prefill_decode_benchmar_001.yaml +479 -0
  137. sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_prefill_decode_benchmar_002.yaml +479 -0
  138. sflow/samples/modular/inference_x_v2/composed_recipes/vllm_agg_benchmark_aiperf_1n_2_009.yaml +408 -0
  139. sflow/samples/modular/inference_x_v2/composed_recipes/vllm_prefill_decode_benchmark_005.yaml +510 -0
  140. sflow/samples/modular/inference_x_v2/composed_recipes/vllm_prefill_decode_benchmark_006.yaml +511 -0
  141. sflow/samples/modular/inference_x_v2/sglang/agg.yaml +117 -0
  142. sflow/samples/modular/inference_x_v2/sglang/decode.yaml +120 -0
  143. sflow/samples/modular/inference_x_v2/sglang/prefill.yaml +120 -0
  144. sflow/samples/modular/inference_x_v2/slurm_config.yaml +35 -0
  145. sflow/samples/modular/inference_x_v2/trtllm/agg.yaml +129 -0
  146. sflow/samples/modular/inference_x_v2/trtllm/decode.yaml +128 -0
  147. sflow/samples/modular/inference_x_v2/trtllm/prefill.yaml +126 -0
  148. sflow/samples/modular/inference_x_v2/vllm/agg.yaml +127 -0
  149. sflow/samples/modular/inference_x_v2/vllm/decode.yaml +126 -0
  150. sflow/samples/modular/inference_x_v2/vllm/prefill.yaml +127 -0
  151. sflow/samples/modular/utils/set_up_dynamo.yaml +131 -0
  152. sflow/samples/self_contained/docker/gpu_monitor.yaml +95 -0
  153. sflow/samples/self_contained/docker/hello_world.yaml +16 -0
  154. sflow/samples/self_contained/docker/multi_node.yaml +31 -0
  155. sflow/samples/self_contained/docker/sglang_qwen3.yaml +180 -0
  156. sflow/samples/self_contained/kubernetes/dynamo_sglang_agg.yaml +469 -0
  157. sflow/samples/self_contained/kubernetes/dynamo_sglang_disagg.yaml +733 -0
  158. sflow/samples/self_contained/kubernetes/dynamo_sglang_disagg_dsr1.yaml +757 -0
  159. sflow/samples/self_contained/kubernetes/dynamo_trtllm_agg.yaml +413 -0
  160. sflow/samples/self_contained/kubernetes/dynamo_trtllm_disagg.yaml +559 -0
  161. sflow/samples/self_contained/kubernetes/dynamo_vllm_agg.yaml +502 -0
  162. sflow/samples/self_contained/kubernetes/dynamo_vllm_disagg.yaml +704 -0
  163. sflow/samples/self_contained/kubernetes/hello_world.yaml +23 -0
  164. sflow/samples/self_contained/kubernetes/multinode.yaml +54 -0
  165. sflow/samples/self_contained/kubernetes/qwen3_8b/README.md +93 -0
  166. sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_dynamo_trtllm_agg.yaml +298 -0
  167. sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_dynamo_trtllm_disagg.yaml +370 -0
  168. sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_trtllm_serve.yaml +223 -0
  169. sflow/samples/self_contained/kubernetes/qwen3_8b/gb_dynamo_trtllm_agg.yaml +306 -0
  170. sflow/samples/self_contained/kubernetes/qwen3_8b/gb_dynamo_trtllm_disagg.yaml +403 -0
  171. sflow/samples/self_contained/kubernetes/qwen3_8b/gb_trtllm_serve.yaml +233 -0
  172. sflow/samples/self_contained/kubernetes/trtllm_serve_agg.yaml +268 -0
  173. sflow/samples/self_contained/kubernetes/trtllm_serve_disagg.yaml +384 -0
  174. sflow/samples/self_contained/local/dag.yaml +48 -0
  175. sflow/samples/self_contained/local/hello_world.yaml +13 -0
  176. sflow/samples/self_contained/local/monitor.yaml +48 -0
  177. sflow/samples/self_contained/local/result_parsing.yaml +81 -0
  178. sflow/samples/self_contained/local/storage_upload.yaml +51 -0
  179. sflow/samples/self_contained/local/storage_upload_all.yaml +53 -0
  180. sflow/samples/self_contained/local/variable_domain.yaml +28 -0
  181. sflow/samples/self_contained/slurm/aiperf_template.yaml +127 -0
  182. sflow/samples/self_contained/slurm/auto_replica.yaml +122 -0
  183. sflow/samples/self_contained/slurm/dynamo_sglang_agg.yaml +341 -0
  184. sflow/samples/self_contained/slurm/dynamo_sglang_disagg.yaml +460 -0
  185. sflow/samples/self_contained/slurm/dynamo_trtllm_agg.yaml +355 -0
  186. sflow/samples/self_contained/slurm/dynamo_trtllm_disagg.yaml +475 -0
  187. sflow/samples/self_contained/slurm/dynamo_vllm_agg.yaml +371 -0
  188. sflow/samples/self_contained/slurm/dynamo_vllm_disagg.yaml +525 -0
  189. sflow/samples/self_contained/slurm/gpu_indices.yaml +123 -0
  190. sflow/samples/self_contained/slurm/gpu_placement_matrix.yaml +366 -0
  191. sflow/samples/self_contained/slurm/infmax_v1_ds_r1.yaml +456 -0
  192. sflow/samples/self_contained/slurm/monitor_mixed.yaml +550 -0
  193. sflow/samples/self_contained/slurm/multi_backend.yaml +89 -0
  194. sflow/samples/self_contained/slurm/resource_release_after.yaml +153 -0
  195. sflow/samples/self_contained/slurm/sglang_server_client.yaml +205 -0
  196. sflow/samples/self_contained/slurm/trtllm_serve_disagg.yaml +481 -0
  197. sflow/skills/AGENTS.md +128 -0
  198. sflow/skills/__init__.py +28 -0
  199. sflow/skills/sflow-code-review/SKILL.md +277 -0
  200. sflow/skills/sflow-code-review/reference.md +158 -0
  201. sflow/skills/sflow-error-analysis/SKILL.md +194 -0
  202. sflow/skills/sflow-error-analysis/error-catalog.md +818 -0
  203. sflow/skills/sflow-error-analysis/scripts/parse_sflow_errors.py +580 -0
  204. sflow/skills/sflow-error-analysis/scripts/summarize_run.py +197 -0
  205. sflow/skills/sflow-error-analysis/scripts/triage.py +130 -0
  206. sflow/skills/writing-sflow-yaml/SKILL.md +335 -0
  207. sflow/skills/writing-sflow-yaml/examples.md +901 -0
  208. sflow/skills/writing-sflow-yaml/schema-reference.md +1081 -0
  209. sflow/skills/writing-sflow-yaml/scripts/check_gpu_plan.py +348 -0
  210. sflow/skills/writing-sflow-yaml/scripts/preflight.py +175 -0
  211. sflow/skills/writing-sflow-yaml/scripts/validate_sflow_yaml.py +691 -0
  212. sflow/ui/__init__.py +8 -0
  213. sflow/ui/rich_tui.py +656 -0
  214. sflow/utils/__init__.py +2 -0
  215. sflow/utils/console_text.py +135 -0
  216. sflow/utils/container.py +232 -0
  217. sflow/utils/extra_args.py +88 -0
  218. sflow/utils/gpu.py +188 -0
  219. sflow/utils/gpu_reservation.py +820 -0
  220. sflow/utils/install.py +159 -0
  221. sflow/utils/logging.py +226 -0
  222. sflow/utils/node_filters.py +115 -0
  223. sflow/utils/parser.py +106 -0
  224. sflow/utils/script.py +162 -0
  225. sflow/utils/slurm.py +45 -0
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: nv-sflow
3
+ Version: 0.3.1
4
+ Summary: A Python CLI tool designed to automate and manage benchmarking workflows on multiple backends.
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: jinja2>=3.1.6
9
+ Requires-Dist: mermaid-py>=0.8.0
10
+ Requires-Dist: parse<2,>=1.16
11
+ Requires-Dist: pydantic>=2.11.10
12
+ Requires-Dist: pyyaml>=6.0.3
13
+ Requires-Dist: rich>=13.7.0
14
+ Requires-Dist: textual>=8.2.7
15
+ Requires-Dist: typer>=0.19.2
16
+ Provides-Extra: dev
17
+ Requires-Dist: ipython>=8.37.0; extra == "dev"
18
+ Requires-Dist: matplotlib>=3.8.0; extra == "dev"
19
+ Requires-Dist: moto>=5.0.0; extra == "dev"
20
+ Requires-Dist: pytest>=8.4.2; extra == "dev"
21
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
22
+ Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
23
+ Requires-Dist: pytest-subprocess>=1.5.3; extra == "dev"
24
+ Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
25
+ Provides-Extra: s3
26
+ Requires-Dist: boto3>=1.34.0; extra == "s3"
27
+ Provides-Extra: monitor
28
+ Requires-Dist: matplotlib>=3.8.0; extra == "monitor"
29
+ Dynamic: license-file
30
+
31
+ # sflow
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ uv venv --python python3 && source .venv/bin/activate
37
+ uv pip install "nv-sflow @ git+https://github.com/NVIDIA/nv-sflow.git@main"
38
+ sflow --version
39
+ ```
40
+
41
+ Already on **sflow v0.3.0+**? Upgrade in place — no incantation to remember:
42
+
43
+ ```bash
44
+ sflow upgrade # latest main; --branch <ref> / --dry-run also supported
45
+ ```
46
+
47
+ No `uv`? `pip install uv` (or `curl -LsSf https://astral.sh/uv/install.sh | sh`).
48
+ Optional extras: `sflow[s3]` (S3 uploads), `sflow[monitor]` (PNG hardware charts).
49
+ Contributing? Skip to [Development Setup](#development-setup) for the editable install.
50
+
51
+ ## What is sflow
52
+
53
+ A **declarative workflow descriptor for massive GPU clusters** that separates _what to deploy_ from _where to deploy it_.
54
+
55
+ **One semantic across every platform — backend agnostic by design.** A deployment's logic never changes: start etcd and NATS, launch a frontend, spin up workers, run the benchmark. Only the infrastructure glue does — and today that glue is rewritten from scratch for every platform. `sflow` consolidates it into a single portable YAML: tasks, dependencies, resources, and launch methods. The **same `sflow.yaml` runs on Docker, Slurm, and Kubernetes** — swap the backend fragment, rewrite nothing. Backends delegate to each platform's native ecosystem (`srun`/MPI, `docker run`, pods and MPI jobs) rather than reimplementing it.
56
+
57
+ **Cluster-level orchestration at scale.** Topology-aware node and GPU placement, multi-node replicas and sweeps, readiness/failure probes, and batch submission — so one descriptor drives hundreds of GPUs instead of a pile of hand-written bash.
58
+
59
+ All four backends ship today: `local`, `docker`, `slurm`, and `kubernetes` (`k8s` / `k8s_mpi`). It is light enough to write and debug a recipe on your laptop and submit that same file to the cluster.
60
+
61
+ ![sflow TUI](docs-site/static/img/sflow_tui.gif)
62
+
63
+ Define _what to run_ in a `sflow.yaml` — tasks, dependencies, how to launch each task, and required resources. `sflow` executes the DAG in order, collects logs, and organizes outputs into a consistent directory structure. Example of a dynamo PD disaggregation LLM inference service workflow:
64
+
65
+ <p align="center">
66
+ <img src="docs-site/static/img/workflow-dag.png" alt="Workflow DAG Example" width="700">
67
+ </p>
68
+
69
+ ## What it's for
70
+
71
+ Any workload that runs in **steps that depend on each other**: build → train → evaluate,
72
+ start a service → wait for it → drive load against it → collect results, stage data →
73
+ process shards in parallel → merge. If you would otherwise write a shell script that
74
+ launches things in order, polls until something is ready, and tidies up afterwards, that
75
+ script is a workflow — and sflow already does the tedious parts.
76
+
77
+ Distributed LLM inference is the *hardest* case it is designed around, not the only one: a
78
+ dozen processes across several nodes that must come up in the right order, find each other,
79
+ share GPUs correctly, and be torn down cleanly when any one of them dies. Whatever survives
80
+ that tends to handle simpler pipelines comfortably.
81
+
82
+ ### The parts you don't write again
83
+
84
+ Each of these is a YAML field, not a page of bash:
85
+
86
+ | Instead of hand-rolling… | You declare |
87
+ | --- | --- |
88
+ | `until curl -sf …; do sleep 5; done` | `probes.readiness` (HTTP / TCP / log-watch) with a timeout |
89
+ | retry loops and backoff arithmetic | `retries: {count, interval, backoff}` |
90
+ | stray-process cleanup, `trap` handlers | teardown runs on success, failure and Ctrl-C |
91
+ | `mkdir -p logs/$(date +%s)`, `tee`, scattered output | one run directory per workflow, a log per task, a run summary |
92
+ | `grep`/`awk` over logs into a CSV | `result:` parsing (regex, named patterns, or JSON) → `result.json` |
93
+ | `aws s3 cp` sprinkled through the script | `uploads:` per task on `COMPLETED`, credentials from boto3's chain |
94
+ | copying config/data files onto nodes by hand | `artifacts:` staged and mounted at the same path on every backend |
95
+ | `for cfg in …; do sbatch …; done` | `replicas:`, or `batch` over a CSV of parameter rows |
96
+ | hard-coding hosts, ports and device ids | `${{ }}` expressions over variables, backend nodes and task services |
97
+
98
+ Plus a live TUI, `--dry-run` for the whole plan, and per-task GPU/CPU/network sampling —
99
+ none of which you have to build.
100
+
101
+ ### One recipe, laptop to cluster
102
+
103
+ **At cluster scale:**
104
+
105
+ - **Multi-node placement** — `resources.nodes` (`indices` / `count` / `exclude`) and
106
+ `resources.gpus` (`count`, or `indices` to pin exact device ids) pack tasks onto specific
107
+ nodes and devices, with conflict detection at plan time rather than a failure ten minutes
108
+ into the run. On Slurm the plan is re-applied *inside* the step by GPU UUID, so
109
+ `slurmstepd` and container renumbering cannot silently land every rank on device 0.
110
+ - **Real ordering** — `depends_on` waits for a process to *start*; readiness **probes**
111
+ (HTTP, TCP, log-watch) make dependents wait for a service to actually be up. `required_by`
112
+ expresses the reverse edge so a workload fragment can attach itself to a benchmark.
113
+ - **Distributed launchers** — `srun` with MPI/pmix on Slurm, `k8s` and `k8s_mpi` on
114
+ Kubernetes, where a multi-node task becomes one pod per reserved node (GPUs via the
115
+ device plugin or DRA) and co-located GPU tasks can be merged into a single pod.
116
+ - **Fleet-scale runs** — `replicas` for fan-out, `release_after` so a later task can reuse a
117
+ still-running server's GPUs, plus `batch` / bulk-input CSV sweeps over a parameter grid.
118
+ - **Results you can compare** — `result:` parsing, `uploads:` to S3, and a passive hardware
119
+ monitor that samples GPU/CPU/network per task, with `monitor.window` log markers to clip a
120
+ report to the phase you actually measured.
121
+ - **Run output that explains itself** — `sflow_summary.log` records planned vs. observed GPU
122
+ assignment, node topology, and external command health (`kubectl`/`srun`/`docker` latency
123
+ and failures); a stalled event loop dumps every thread's stack to `loop_stalls.txt`.
124
+
125
+ **On one machine:**
126
+
127
+ - **`local` backend, no scheduler** — the Quickstart below runs a DAG in a few seconds.
128
+ - **`--dry-run`** renders the full plan — placement, GPU slices, and the exact commands —
129
+ without touching a cluster, so most recipe mistakes surface before you queue anything.
130
+ - **`docker` backend** runs the same containerized tasks on one box, reserving GPUs per task
131
+ so several `sflow run` sessions can share a workstation without colliding.
132
+ - **Composable fragments** — a workload YAML pairs with a backend fragment, so the recipe you
133
+ proved locally is the one you submit to the cluster. See
134
+ [`examples/modular/backend_agnostic/`](examples/modular/backend_agnostic/).
135
+
136
+ **The same workload, three platforms.** [`examples/modular/backend_agnostic/`](examples/modular/backend_agnostic/)
137
+ composes a backend fragment + a workload + a benchmark. Moving platforms means swapping one `-f`:
138
+
139
+ ```bash
140
+ # Kubernetes
141
+ sflow run -f backends/k8s.yaml -f workloads/dynamo_common.yaml -f workloads/dynamo_trtllm.yaml -f benchmark.yaml
142
+ # Slurm — same workload, same benchmark
143
+ sflow run -f backends/slurm.yaml -f workloads/dynamo_common.yaml -f workloads/dynamo_trtllm.yaml -f benchmark.yaml
144
+ # One local box, containers
145
+ sflow run -f backends/docker.yaml -f workloads/sglang_serve.yaml -f benchmark.yaml
146
+ ```
147
+
148
+ ## CLI at a Glance
149
+
150
+ | Command | Purpose | Key Flags |
151
+ |---------|---------|-----------|
152
+ | `sflow run` | Execute a workflow | `--dry-run` `--tui` `--set` `-f` (multi-file) |
153
+ | `sflow batch` | Generate / submit sbatch scripts | `--submit` `--bulk-input` `--row` |
154
+ | `sflow compose` | Merge multiple YAMLs | `--resolve` `--missable-tasks` `-o` |
155
+ | `sflow visualize` | Render DAG graph | `--format png/svg/mermaid` |
156
+ | `sflow sample` | List / copy examples | `--list` `-o` |
157
+ | `sflow skill` | Export AI agent skills | `--list` `-o` |
158
+ | `sflow upgrade` | Reinstall sflow in place (alias: `sflow update`) | `--branch` `--dry-run` `--force` |
159
+
160
+ ## Introduction
161
+
162
+ Start here:
163
+
164
+ - **User docs**: `docs/user/intro.md`
165
+ - **Release notes**: `docs/release_notes/` — start with
166
+ [v0.3.1](docs/release_notes/RELEASE_NOTES_v0.3.1.md) for the current breaking changes and
167
+ upgrade checklist
168
+ - **PLC docs**:
169
+ - SPP: `docs/plc/sflow_spp.md`
170
+ - SRD: `docs/plc/sflow_srd.md`
171
+ - SADD: `docs/plc/sflow_sadd.md`
172
+
173
+ ## Quickstart
174
+
175
+ If you just want to validate the workflow engine locally (no Slurm required):
176
+
177
+ ```bash
178
+ uv venv
179
+ source .venv/bin/activate
180
+ uv pip install -e ".[dev]"
181
+
182
+ sflow run --file examples/self_contained/local/hello_world.yaml --tui
183
+ ```
184
+
185
+ That example is the whole file — no backend block, no operator, no boilerplate:
186
+
187
+ ```yaml
188
+ version: "0.1"
189
+
190
+ variables:
191
+ WHO:
192
+ description: "who to greet"
193
+ value: Nvidia
194
+
195
+ workflow:
196
+ name: local_hello_world
197
+ tasks:
198
+ - name: hello
199
+ script:
200
+ - echo "Hello ${WHO}"
201
+ ```
202
+
203
+ With nothing declared, sflow runs on the `local` backend with its default operator. Add a
204
+ `backends:` block later and the same tasks run under Docker, Slurm or Kubernetes.
205
+
206
+ ## Development Setup
207
+
208
+ This guide will help you set up the development environment for contributing to `sflow`.
209
+
210
+ ### Prerequisites
211
+
212
+ - **Python 3.10 or higher**
213
+
214
+ ```bash
215
+ python --version # Check your Python version
216
+ ```
217
+
218
+ - **uv** (Python package installer and resolver)
219
+
220
+ If you don't have `uv` installed, you can install it using:
221
+
222
+ ```bash
223
+ curl -LsSf https://astral.sh/uv/install.sh | sh
224
+ ```
225
+
226
+ Or via pip:
227
+
228
+ ```bash
229
+ pip install uv
230
+ ```
231
+
232
+ ### Getting Started
233
+
234
+ 1. **Clone the repository**
235
+
236
+ ```bash
237
+ git clone <repository-url>
238
+ cd sflow
239
+ ```
240
+
241
+ 2. **Create a virtual environment**
242
+
243
+ ```bash
244
+ uv venv
245
+ ```
246
+
247
+ 3. **Activate the virtual environment**
248
+
249
+ ```bash
250
+ source .venv/bin/activate
251
+ ```
252
+
253
+ 4. **Install the project with development dependencies**
254
+
255
+ ```bash
256
+ uv pip install -e ".[dev]"
257
+ ```
258
+
259
+ This will install:
260
+
261
+ - The `sflow` package in editable mode
262
+ - All runtime dependencies (typer, pydantic, pyyaml, etc.)
263
+ - Development tools (pytest, pytest-cov, ipython, etc.)
264
+
265
+ 5. **Run unit tests to validate your setup**
266
+
267
+ ```bash
268
+ pytest
269
+ ```
270
+
271
+ ## Contributing to the project
272
+
273
+ Please follow the Git Flow process defined here: https://coda.io/d/_d0pJwz5IXhP/Manage-Git-branches-and-workflows_suLlBLYx
@@ -0,0 +1,225 @@
1
+ nv_sflow-0.3.1.dist-info/licenses/LICENSE,sha256=Rq5fDcLgahjN6LBr20Wr6gtuKNFp5u_yBpU2eAMEz24,9793
2
+ sflow/__init__.py,sha256=KG-Eb0M7vUk2a0nVOtmeDLgJA9-WtffhJ8DeOAOqMn0,467
3
+ sflow/__main__.py,sha256=9GUMCnEIL3CSIIqN6jiN5mXu94bI9qRFYMt-Z48k9O4,202
4
+ sflow/_version.py,sha256=lOWWIGJeBi0KkFopWU_n3GH71C1PsaZ-ZYDfxFkne6c,511
5
+ sflow/logging.py,sha256=o-iD3gexRGFuRg4Dfk_BhFQmlPlb_y_kLke43kIUSM0,12219
6
+ sflow/resolution.py,sha256=13PiiNAyc-EpxcjRo3xhdOOeQseCU3ADREAiw30TDwE,43240
7
+ sflow/runtime_info.py,sha256=j7GOqYftkIfkPKZVYaUlFkmph4cZX5nT99n48ErQIc0,8419
8
+ sflow/app/__init__.py,sha256=sybvrqXMGE2TCRVTIpmWaokYwd15IWnu--xDKWfikJY,178
9
+ sflow/app/assembly.py,sha256=_RcKcNFMDdoybKAUrpFVZWLLM-GC3vOKhi2r-KKPebI,77900
10
+ sflow/app/backend_lifecycle.py,sha256=gL9tS66F8N2dt4nyQkgjMHYRDT4clg4ZZKOJ9f_QZnE,9790
11
+ sflow/app/monitor_cli.py,sha256=y8aWG6NpVczfqPxULsZBK4y1xUgeU421FBBkrBHaa5o,6269
12
+ sflow/app/monitor_planner.py,sha256=Mp9FVDnaQAIE2WquuUVOwRiShv-yCbxNTjhYwm5Y2-k,32258
13
+ sflow/app/resource_planner.py,sha256=2_2lcaNE0PTv5sROW_mQudVfZtXu8dq-WXtgchGIC-Y,71255
14
+ sflow/app/run_support.py,sha256=fcjF5Fspiaxu16JeYR0wqhbdqpyIwEtXxMCBV-qsIJg,13681
15
+ sflow/app/sflow.py,sha256=DlrNp-LYalGPp93W1_xuF-krYv3Z_GT38MyvbEXWpSk,75812
16
+ sflow/app/task_context.py,sha256=DGpTvxeJvLr1XOxtILehJL0gYCLG1TJkxW8SV2qtT0s,8644
17
+ sflow/cli/__init__.py,sha256=G4aix04KjpICghx1qnByQUWFd3doBt0ACHeIhVpxq3o,2544
18
+ sflow/cli/_args.py,sha256=SQlbSo2SDR8GWbdzff_vkNOZji477pKtcqMTanS8nBg,4194
19
+ sflow/cli/batch.py,sha256=4kF6CPCNdRIQgGojlpVYm9kMSgYv1tJA8TkPrIwuxSA,142370
20
+ sflow/cli/compose.py,sha256=AyfHTo_mwUjpdBz-I8G-lW88iODJ1pi-woDKKR2WqnU,21778
21
+ sflow/cli/run.py,sha256=95Uq7Qm4QfKzoXA_YjpWHxyY2EiF2mkthOiyJVfTHu0,27877
22
+ sflow/cli/sample.py,sha256=TVPsBQb38e3uIVaF1i-hU9WYIWEX4kWxgXTDsRoaj7U,18305
23
+ sflow/cli/skill.py,sha256=O9SD5F1Tr5zqxBuEmjuwerfGMQ4NjkD-w1RtCaR03Hk,12006
24
+ sflow/cli/upgrade.py,sha256=i28h6MWgmTE2fAeiId5cN-qlii5PyTbaGm1RS01T6zs,10379
25
+ sflow/cli/visualize.py,sha256=lSXebXCHKnhezydg8VXhdirxm4ks5CSfLYSdesApGmQ,5829
26
+ sflow/config/__init__.py,sha256=o1lGlLGXRnDEQ09cXnAYR7aiakCju6vzyZ-LDPz7h4U,186
27
+ sflow/config/loader.py,sha256=rr_Uwqbu7e8ux8uYvORDB5UyjvlYIY7NEK8Ie1_PDj0,30041
28
+ sflow/config/resolver.py,sha256=Huk9RT56_Y9Qd7lAdtdaQjO16rcfg53BfxmSLOT6pIQ,393
29
+ sflow/config/schema.py,sha256=eYK5d2fd6CG8a01hVWYYRuQ6Fo0rsHhCa9TeNlv6LjQ,54886
30
+ sflow/core/__init__.py,sha256=_ATs4J7QbIfvvehtX3N8R3PXKcQpfPZkviBOlgjx1_4,185
31
+ sflow/core/artifact.py,sha256=J_qKNnPRoDn58TszHQ7nTCge5Ojc9_8VPaOqhtYthoI,1700
32
+ sflow/core/artifact_registry.py,sha256=h5wDPVHYXMZhFRuLWfwNG401995XU7lt022AgqKbn-0,3843
33
+ sflow/core/backend.py,sha256=V-Vpj0U9L4mIlKytALCsI6uLy3M7kTaQKrj1HgcACms,9744
34
+ sflow/core/backend_registry.py,sha256=YOj6BGUSz3uTq5gSXUDMqmeNdhQUOixJct9WLeDfdHI,2328
35
+ sflow/core/command.py,sha256=EOyJ6ivno5UlSRqcqjXOvLUzzZfFJOQRR9r0190mBM8,3293
36
+ sflow/core/command_log.py,sha256=w9Zvw957D7H2Sc9ce9Tym1e2RQugVzvLNBjnXIxBSUc,4155
37
+ sflow/core/command_trace.py,sha256=Nn4MpsQakTYDyThjBYz6PnfVScqw_DrFtEHSfhCKGPc,15538
38
+ sflow/core/compute_node.py,sha256=5lGCCz6P6L09r2aqIRKS7oA6TR9C_i4Q957cSoosfi0,1331
39
+ sflow/core/constraints.py,sha256=cxePJLjTz4dB7OUStjbAUzrZMc-9PzLMuUTyc0j9NsU,582
40
+ sflow/core/context.py,sha256=EcHLpzxOOoXuI1JHBPeGaB3fzHcEzLODJ0TrmM8iaN0,1783
41
+ sflow/core/dag.py,sha256=mzn6dm6wZ4bNmsSKlbC9lNWV8fK1rp3bCiHbbHY8_i8,15612
42
+ sflow/core/execution_summary.py,sha256=rRpK9IzV8HQQVuB_U-zimoXsZNHLhQFQIE-j4OvBR0c,41884
43
+ sflow/core/kubectl_config.py,sha256=D66Ht69kG10c9yvp_rD5Qc4Mc9sZ6XYh0swlsTrh2aM,7137
44
+ sflow/core/launcher.py,sha256=ALva8yAYVprZ9MeRIobwAMTNSrRd378RM7qtCmCones,17884
45
+ sflow/core/log_offload.py,sha256=HfV6xUYfTUqO7eJ6V9rdeEqNfrW8iut1sL6FI25CeAE,8177
46
+ sflow/core/loop_watchdog.py,sha256=TJwoMStg549HU1nIaUv4W6sGrf-WeDalWOwxYwO8Yew,7977
47
+ sflow/core/monitor.py,sha256=IpSARHK9_u_4P1vkCLWXXe4IKbrOJU5VhXOJrGaBVSQ,10714
48
+ sflow/core/operator.py,sha256=1kJ3rVj5Qt_gxXfzdyg5rLCrqKrD4Z1QywIKxi9pxKc,9515
49
+ sflow/core/operator_registry.py,sha256=D_rW6RMKWNqFOC-zH25uz0z5s9Kpliu1I4gkIr5DdYA,5056
50
+ sflow/core/orchestrator.py,sha256=VfAcyk4uHT4uFBjH5tgEAP5ZwBBj8SmUeELN8UkKJhg,70945
51
+ sflow/core/outputs.py,sha256=11j6kjd_-u4xRfLNoeD7c0UqvpTg1MGJ1_53Nku3XvU,3730
52
+ sflow/core/probe.py,sha256=BAnJgtw6lvySyUBH8_tzyE6fN2Lvweks8R3kfO5dz5o,7340
53
+ sflow/core/probe_transport.py,sha256=riMgd72yMj5xBDSSlDN1kboPZ9SeeTL4sa4n0Pac0dQ,3163
54
+ sflow/core/replica.py,sha256=XLO09Ei8g0lU7hYlzKCvhvQhLFBe5CBwE4v2PqK9xWY,142
55
+ sflow/core/resource.py,sha256=Mnr-39mKp9fZvRevooYruH1_026Yxt6IzAw37I_m-tw,237
56
+ sflow/core/results.py,sha256=0ZIjMPVZn3lg4idhhXD9--0iN8NQ3C8U_T5Eplx8obs,23291
57
+ sflow/core/state.py,sha256=ppXziKZ79TwwDqtuMI203_GU3R7SC9M_PDETe95Fwzg,2144
58
+ sflow/core/storage.py,sha256=rQ2iX4Bz4E5ls4wVzZYRcU_Lf4L1jshaUC9YvJ_DsLQ,1703
59
+ sflow/core/storage_registry.py,sha256=q8oZUle4XqwMQY8IjLOEhJrHgTNnChu5df1CzOK9HhQ,2346
60
+ sflow/core/task.py,sha256=KqFe2OmuU5zGnKIKqbf2lGtSewTQlwZpmvrzdLN3trI,13455
61
+ sflow/core/task_graph.py,sha256=Q7LbZkizCppsxKfFQp3APpYL4GS_vp1n3mjU4_Baftk,2091
62
+ sflow/core/uploads.py,sha256=IEtMXYqLtYATgMs0wvtp7rsNgh1C2U8i3ZlB0UZd0HY,18895
63
+ sflow/core/variable.py,sha256=TPLF5Ew3Y5kkEjl6mGKsfM3Ogw49uLkc97rQ2CMo3II,7741
64
+ sflow/core/workflow.py,sha256=alWhEs-rYeYouP1qi-CBbtqAnSo5nvYhwZs8c49eTtE,911
65
+ sflow/monitoring/__init__.py,sha256=Mly7uAhPCoUoGyKx3hB2HmV3LchTmuejWRtvVTspBig,1652
66
+ sflow/monitoring/hardware_monitor.py,sha256=f7ZMxZo7nDAkATGGaekOHbCYz63fuxvUXfcIMb8o4Og,12044
67
+ sflow/monitoring/postprocess_monitor_timeline.py,sha256=HTiNDFoB0W7O5gZLaDNzk9v2Us0wsGyV32PjOBADw5c,88821
68
+ sflow/plugins/__init__.py,sha256=dBom1ctypWOKJJqiPPCmxkqg4yaeFtOLkSUsR3BTgAw,185
69
+ sflow/plugins/artifacts/__init__.py,sha256=rTujp5NnX0r4TCJI6bsIPq8XIQHD2U8ZLCv-OdID3dY,644
70
+ sflow/plugins/artifacts/docker.py,sha256=D6rIj67vWXTNwWpWUnA-EOqvuyQW_Evk-ObsCdijeKU,1234
71
+ sflow/plugins/artifacts/http.py,sha256=m8xAK0C8OdgE1cNk14-4aYBJWyOZw-Yyagz9kJJ2eFQ,1525
72
+ sflow/plugins/artifacts/huggingface.py,sha256=4WgYckj-8AUNyy-8Qhye8_c6ot8VOLfSxb5uecXcxwY,1305
73
+ sflow/plugins/artifacts/local.py,sha256=vYeKkd8KemMa3S5Vh-G08hJZJ__o3H-4pBnapurUp2k,6529
74
+ sflow/plugins/backends/__init__.py,sha256=Th2rPBpKf1lRYhwCX5hHu9-s7jaMfM5H6wvvvdyHano,489
75
+ sflow/plugins/backends/docker.py,sha256=IYaeAYoXNt7LxW3MMYCsE0g_IrWaFYyfgUQ08KvvkYI,16863
76
+ sflow/plugins/backends/kubernetes.py,sha256=ZDgql0NXONM9Vyf9hovqfraZ3hCJI10u-_WomM2r2No,168221
77
+ sflow/plugins/backends/local.py,sha256=-nFLFVNfNAomKtp8emMZ5_9CMBkfjsiNeFRXhRyIstk,5238
78
+ sflow/plugins/backends/slurm.py,sha256=dTbzdOUpPvGhqBS034xhGYufW93IUCBpKoGtn8RCHKI,33773
79
+ sflow/plugins/k8s/__init__.py,sha256=2jZCDE0VF4IbwKc0yU6xvSQJly-4eerlwrIgqr_geyo,740
80
+ sflow/plugins/k8s/capabilities.py,sha256=P_JixQvgPo5VlYYUBhKOVYCawt5WEZ_oKY_aEtQk-oI,4819
81
+ sflow/plugins/k8s/lifecycle.py,sha256=RTtZMqLrVRgQ6f49c4kcXfuYwbJjKYqLO9Flsi-JG1E,60424
82
+ sflow/plugins/k8s/log_demux.py,sha256=6Pe-bOwEOvNZJ-59x8Wd7JlCrM8DqW4K0rMy3MfDt6o,7742
83
+ sflow/plugins/k8s/mpi_bootstrap.py,sha256=pVOv_oCj12J_IIQSYi8hKcbc_G5c6qcrSETV04aPIn8,41089
84
+ sflow/plugins/k8s/mpi_lifecycle.py,sha256=aFDlglHuArnGiidzSKYUNwYpyW4ba43LUsOmxJiy7eU,5667
85
+ sflow/plugins/k8s/probe.py,sha256=eGO-BCvcbvb2LSaso11XOMNSgaKfKBjeyowYKYytgDM,4937
86
+ sflow/plugins/k8s/rdma.py,sha256=MPWYyBuM9MmK45ua6pV9OdpJPGzwvZjsLmQi-Ms_EJw,15927
87
+ sflow/plugins/k8s/rdma_preamble.py,sha256=vQX5x1A_U7eFG0LQekWTWg0DH5VGIRNeaUP3Y666J5s,18228
88
+ sflow/plugins/k8s/render.py,sha256=5jLvtQ1hKKP9K_5dNjNdOz9XXI8Rd7lUtVS00cJz-gM,47738
89
+ sflow/plugins/k8s/shell.py,sha256=jcU1YIV10aht3Y-NoF4gveZLyOw8AR4yoS74bA3IL90,29136
90
+ sflow/plugins/operators/__init__.py,sha256=13eisPSQ2KhPVmuocP2ghaZFRp1oZ3OMqa2psBzujwk,926
91
+ sflow/plugins/operators/bash.py,sha256=SpJkH7RaWByPXew_9j17mykK5ql9-2ALYJY4kvyogIY,2702
92
+ sflow/plugins/operators/docker_run.py,sha256=LmDVIeXTjRCtBMJl69g6JtkpsjTY_plPmylLuA-VZqA,31867
93
+ sflow/plugins/operators/gpu_placement.sh,sha256=Qp8TieR6rThfRJPmp1-2YBIWrU0sy9Z8mikR8OLsEjk,14155
94
+ sflow/plugins/operators/k8s.py,sha256=lJpR8OKmiMXEHrJ7RTz0ppOyJARrLWfbARbfmveiB9Y,1294
95
+ sflow/plugins/operators/k8s_mpi.py,sha256=lgQO-SAvCIvz3goHYfeZ0SuA_VeVPrWLquYYHMT4e-A,38682
96
+ sflow/plugins/operators/k8s_operator.py,sha256=bi9G87xNtc1H0aPpL0eOUW6JBI9ye88Yxq_EAkSh4ks,140600
97
+ sflow/plugins/operators/python.py,sha256=1A-VCgluu0R8yXm_PWNzXiwULZF0VLAAWJnVPAL20XQ,2179
98
+ sflow/plugins/operators/srun.py,sha256=Z7nqlK1cB7O9CDEz4R2kxRybAHHHtiF8PcbN7NPGwvc,26884
99
+ sflow/plugins/operators/ssh.py,sha256=fTh56XZC448FEdenwAY4g7JEGiPIR9NMUr3DsrYoBzk,2340
100
+ sflow/plugins/probes/__init__.py,sha256=38L6FxxmQsBGDnPqAoc02oCqQDilAGrW248S3UH6pRk,485
101
+ sflow/plugins/probes/http.py,sha256=NStiwRG0p9AwogDg00qzwlywLWCmHLZSkQNHWJs9bLg,3004
102
+ sflow/plugins/probes/log_watch.py,sha256=Cm4L5KYY8NsRPkSRLn7Mcp2UXzy3lK02e6T7w0C6GxA,9261
103
+ sflow/plugins/probes/tcp_port.py,sha256=yXJnDI5qFu656Rd32Hh2Qq6URjPNaCg18xGCYqqJq80,2531
104
+ sflow/plugins/storage/__init__.py,sha256=QCXFvmG_qmsAOKoR45S_sDsOG3fcxdXe0xjKNuFJwUA,495
105
+ sflow/plugins/storage/s3.py,sha256=Z6JPqQQaN0CpvfJlfq29tWCFNNT_GT4d8dm7ZSN4kjc,8256
106
+ sflow/samples/__init__.py,sha256=cTsb3bQgsMZwe3TmHczc5rzjunHlrh0ZzJ26NwycLmI,2701
107
+ sflow/samples/modular/backend_agnostic/README.md,sha256=54ti90KBAulOfQx-rElaXctS-yIeRpFWDGOq85kGHfo,8286
108
+ sflow/samples/modular/backend_agnostic/benchmark.yaml,sha256=vjV_jEXRMwVVkohwJ29rJ-h6pYJaw6iyko33dtzpQJQ,2300
109
+ sflow/samples/modular/backend_agnostic/backends/docker.yaml,sha256=SibSghXfziOTIDjzU-jqn64Yr197imYp7gqS-kQq-ME,3393
110
+ sflow/samples/modular/backend_agnostic/backends/k8s.yaml,sha256=1Ap7CCnP8PfPLVnpao_87HcaVTfTiWkep5TCflGCvI0,1655
111
+ sflow/samples/modular/backend_agnostic/backends/k8s_mpi.yaml,sha256=-upnxICaOWmtBBX98xNP_6Qy7tn8Ghlfi9MGfV9Bff0,2008
112
+ sflow/samples/modular/backend_agnostic/backends/slurm.yaml,sha256=2o0jzjIbPalPIFKCmuZBvNBDizCfqoQ2w31p85oxzwQ,2092
113
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_common.yaml,sha256=itdjSwWYSM86RhONCasrZZ_X6ZCIQZxr1Ugz-el8bEA,2226
114
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_sglang.yaml,sha256=Y2HRpMrm36F-vrT6xVrKSg37bpxT6K-zbxiB_JSL9JU,1936
115
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_sglang_disagg.yaml,sha256=u3Jjcq6uYsEOq32zDXghN_8mYzqRVHZOG-BibHnbVh4,4721
116
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_trtllm.yaml,sha256=haMR5i643Y8XGbsWwrGWSK5tiWBSH7EmWMIJxz9c7bo,4034
117
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_trtllm_disagg.yaml,sha256=kLs4ckLSC9P-3LHjDq8QaKt7PBWbBUC5XY4Yz__Zbmw,6223
118
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_vllm.yaml,sha256=4_1xh3P9fUFbM_GKUeUryzCRqbDLo9-VKhYBiTAhhQ4,1860
119
+ sflow/samples/modular/backend_agnostic/workloads/dynamo_vllm_disagg.yaml,sha256=nxGf2d6QKsBAPbVetV1VSEEXGX2tyZJ4F4uk4JxqP-I,5201
120
+ sflow/samples/modular/backend_agnostic/workloads/sglang_serve.yaml,sha256=AiASpbARxiaMtxEzJGbc74KQLXQQkM-uut6VJseLupY,1764
121
+ sflow/samples/modular/backend_agnostic/workloads/trtllm_serve.yaml,sha256=zvudd0lkXk9-gYlp-5K-PnppNFlwIYPB_AdJwKKa7RY,2555
122
+ sflow/samples/modular/backend_agnostic/workloads/vllm_serve.yaml,sha256=0RgEWgvLm3TqHruThNH-BICCzZ7FAjcoxLL3_lFu_xE,1874
123
+ sflow/samples/modular/inference_x_v2/benchmark_aiperf.yaml,sha256=iQ19DMfOuqeYEvGkGn_TOd52XAWIYgV1_8LKKL3HUpE,2843
124
+ sflow/samples/modular/inference_x_v2/benchmark_infmax.yaml,sha256=tM7gwju5WCCPrx4kojyEyaQPT064Y2eQz9IJhIYJsXg,2944
125
+ sflow/samples/modular/inference_x_v2/bulk_input.csv,sha256=vim5QWqsaSfa8TxupX1TLKngzESwS5W0Qg_OCU_W5AM,2181
126
+ sflow/samples/modular/inference_x_v2/common_workflow.yaml,sha256=qEQR4EW-fseRH5E6mg7GZHI2Rp9r7xUGlgYnnSFQWLg,12509
127
+ sflow/samples/modular/inference_x_v2/slurm_config.yaml,sha256=YiLm8o36HVP9Ur5MdOtXW3fR8sdu9ROtzWF1k6nlvZk,969
128
+ sflow/samples/modular/inference_x_v2/composed_recipes/sglang_agg_benchmark_aiperf_2n_008.yaml,sha256=Vk5TNySoLfy3HUw7Asp80dVi6jfAN295wAx7EmNH-yk,11608
129
+ sflow/samples/modular/inference_x_v2/composed_recipes/sglang_prefill_decode_benchmar_003.yaml,sha256=UJMuW6XvayOrkTrUyHG-6ie4J66iTshaf5jJ5caiQa8,13894
130
+ sflow/samples/modular/inference_x_v2/composed_recipes/sglang_prefill_decode_benchmar_004.yaml,sha256=5Pw0hP-uD6ioNQ9RAnI0eQWt-ojCafMhYLYeP9fusr4,13911
131
+ sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_agg_benchmark_aiperf_1n_007.yaml,sha256=ahphPJzrRh9n-0OAFLoWPeFF1ZQZgF52Wf-hr8VigL8,11730
132
+ sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_prefill_decode_benchmar_001.yaml,sha256=y2brh7HVOvNrdCY9TgdvcXY9Y9phgshnKx-2rlLtjlU,14007
133
+ sflow/samples/modular/inference_x_v2/composed_recipes/trtllm_prefill_decode_benchmar_002.yaml,sha256=6OBVXV9Nwul8v7SjsHPq7Xt6-X1OHoqVSDuzkRflV_0,14007
134
+ sflow/samples/modular/inference_x_v2/composed_recipes/vllm_agg_benchmark_aiperf_1n_2_009.yaml,sha256=KizqHNWGVNvBjixT8MyUBarEatSgjdYwXr5GcEWWmc4,12544
135
+ sflow/samples/modular/inference_x_v2/composed_recipes/vllm_prefill_decode_benchmark_005.yaml,sha256=j3UE7OHX62YY3Zw1XpGooJHSKRdGpoNe4NcKz0WgxaA,15468
136
+ sflow/samples/modular/inference_x_v2/composed_recipes/vllm_prefill_decode_benchmark_006.yaml,sha256=1d0iG-QYoeC3bMrYAzVbdkL3A65F-lRFpW4uuKQVIHY,15477
137
+ sflow/samples/modular/inference_x_v2/sglang/agg.yaml,sha256=TJUhx6PMG2adKaF10y32bK_ZyzaWa7lRvJT4pBC6iok,4310
138
+ sflow/samples/modular/inference_x_v2/sglang/decode.yaml,sha256=L8IDHS4Y-ihfGFQnFMC13V59Yhs5vgcj_SXZaqrNUNo,4554
139
+ sflow/samples/modular/inference_x_v2/sglang/prefill.yaml,sha256=Fc3obZk4Mktc7tHV0zHAhs30b_SapUYKo3CkZd9t9qQ,4541
140
+ sflow/samples/modular/inference_x_v2/trtllm/agg.yaml,sha256=9K16wtKm7DAaY7i9q_lMPYGd5n40xmpFkNe-_0a3ugE,4272
141
+ sflow/samples/modular/inference_x_v2/trtllm/decode.yaml,sha256=sAW8IGqA5uCPAmdL-zsTvWv33SgTqcEJS68xMFm84k4,4341
142
+ sflow/samples/modular/inference_x_v2/trtllm/prefill.yaml,sha256=6RfwZ_PF9ARgl3q97QaoikllvAHZ4miaRtKhj-cghM0,4252
143
+ sflow/samples/modular/inference_x_v2/vllm/agg.yaml,sha256=OOEx6HG2V9PlOzZgbyIfpJZV_fRXWgxyxcRemQyIYYc,4722
144
+ sflow/samples/modular/inference_x_v2/vllm/decode.yaml,sha256=wKWDnar7D7Z4_whpjJCTSQFWAcism4F7rRAeyVSDmSQ,4707
145
+ sflow/samples/modular/inference_x_v2/vllm/prefill.yaml,sha256=32_KpNf7vuDs2mCMR4AU7izLSfF3aQjv0CR5U17ZTPk,4732
146
+ sflow/samples/modular/utils/set_up_dynamo.yaml,sha256=7G6puwtk4FkUSdrdlOV33Cp2JlvK7DSMj0xowQg8jpo,5794
147
+ sflow/samples/self_contained/docker/gpu_monitor.yaml,sha256=PGM6KLes8hJzbVSVhHOO_TT9PtlxL3batsuzmNeN9Y0,3367
148
+ sflow/samples/self_contained/docker/hello_world.yaml,sha256=LiU3JyaI9-ZIpDXw81v-lhbU9c1KaIVrDnMHF1-0hVg,250
149
+ sflow/samples/self_contained/docker/multi_node.yaml,sha256=rDQ-4mu49BiYlJUlr6lQo82OliJ4ScYGDjK9KMhstXY,751
150
+ sflow/samples/self_contained/docker/sglang_qwen3.yaml,sha256=-AT0osYqhgQhdus7EJ_jkJxTUE3LkU86CjpSwapkceM,6783
151
+ sflow/samples/self_contained/kubernetes/dynamo_sglang_agg.yaml,sha256=eTYARRpUHJXVUc_T67vZd3V1oAMQs2uvns9Ynje_mYQ,20291
152
+ sflow/samples/self_contained/kubernetes/dynamo_sglang_disagg.yaml,sha256=pCJ4OICT3GJowFZXW_jt9kDecluhul_KSBgQBkamLjk,35068
153
+ sflow/samples/self_contained/kubernetes/dynamo_sglang_disagg_dsr1.yaml,sha256=ymvH4HbBdlvP9jLlwAEVMIodq2I1MogT81cv0bIfkYM,36375
154
+ sflow/samples/self_contained/kubernetes/dynamo_trtllm_agg.yaml,sha256=cb3Fw_yLhssyUnUu6MU7Pkaf1Swe0AHayZaqQu_KuZE,15435
155
+ sflow/samples/self_contained/kubernetes/dynamo_trtllm_disagg.yaml,sha256=0P0DRcAD-cDUidxE8-U7RAmqGu_ZasB0645CaXAn9HE,21458
156
+ sflow/samples/self_contained/kubernetes/dynamo_vllm_agg.yaml,sha256=HqzBZH9fU-XVvM6XT40UrVbr_UVPO9uGKUeQFqfFzDw,22249
157
+ sflow/samples/self_contained/kubernetes/dynamo_vllm_disagg.yaml,sha256=9B3ATL9cyDZ45sdZZtD7eqWJ5WeTbgP9l5MexBUtI68,31632
158
+ sflow/samples/self_contained/kubernetes/hello_world.yaml,sha256=gBD8sH8hLvJxBXN6_jFEVDnKrHIDJ1584LfSwAIiPtM,433
159
+ sflow/samples/self_contained/kubernetes/multinode.yaml,sha256=h02ErpG9umSIzgLEm-twEGb3SCEdh0CiJcLvZpSHoN8,1761
160
+ sflow/samples/self_contained/kubernetes/trtllm_serve_agg.yaml,sha256=p8XQ8tcd8OiQMxRAK91dqI8sH2qQe-3ooiFq7Z7893M,9789
161
+ sflow/samples/self_contained/kubernetes/trtllm_serve_disagg.yaml,sha256=4gIOzTl3s0nBJwfVLzrJV7JtaVfyoTB2gGYY72btRYw,14176
162
+ sflow/samples/self_contained/kubernetes/qwen3_8b/README.md,sha256=Ss-yoi1AGlEcAWTg13EG4vbBsxyPtsT45VeQzPoxz10,5018
163
+ sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_dynamo_trtllm_agg.yaml,sha256=41-Ajdq6_y3QoKxUtHyZ5KEoo95OouQSP4xFYoVc_gk,9727
164
+ sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_dynamo_trtllm_disagg.yaml,sha256=NDR5fugiGkJLU3vM8hxB7xj2lGr0-YZRMPCr8cqHBZM,12422
165
+ sflow/samples/self_contained/kubernetes/qwen3_8b/dgx_trtllm_serve.yaml,sha256=IHZS9w_yLhzOG1erCCcJMbueMkYuuXXn_nBrbGBBOkk,7235
166
+ sflow/samples/self_contained/kubernetes/qwen3_8b/gb_dynamo_trtllm_agg.yaml,sha256=NiFGBWBHyMrN757se_Zq_GlAFshGA6fMzvKcRu0Ad2E,10406
167
+ sflow/samples/self_contained/kubernetes/qwen3_8b/gb_dynamo_trtllm_disagg.yaml,sha256=19xgpQdWV10Gl-nYG40j2c1Uoodk91s61lFymFraFnY,14957
168
+ sflow/samples/self_contained/kubernetes/qwen3_8b/gb_trtllm_serve.yaml,sha256=iAXQebekm4Z-4wKOkUT6G_Zdbq8tF1tDD8Gt6I3ifgs,7948
169
+ sflow/samples/self_contained/local/dag.yaml,sha256=HqbJOb87FezeqfvjdKpeM1ouF76a-et9BBavkPL1fVY,1790
170
+ sflow/samples/self_contained/local/hello_world.yaml,sha256=STTS7FEeKfA017rnxg_5Gu6ipyc26h5fGRCquLOKhTE,192
171
+ sflow/samples/self_contained/local/monitor.yaml,sha256=A0SH9NK33NMm15SirrGtJ7i9WQkv8ehL9fcQMZSOa2U,1540
172
+ sflow/samples/self_contained/local/result_parsing.yaml,sha256=oxn6y77CDLbAyk2Kb9NClQYbnzH1i2COSENEraOJL3g,2662
173
+ sflow/samples/self_contained/local/storage_upload.yaml,sha256=ALQ8Loh-OyrLgiNPEgYzLuQdcUV_Qtz-7Ts7Mm9_J4c,1888
174
+ sflow/samples/self_contained/local/storage_upload_all.yaml,sha256=YgPaSjbPCuc5pFmnMLatk9Oj7l-XpfW9EwuN8ZplurU,1923
175
+ sflow/samples/self_contained/local/variable_domain.yaml,sha256=YvymxgEypTJQJH_l_3WmcIqXSyIz6_oJK9BTdJy7yno,766
176
+ sflow/samples/self_contained/slurm/aiperf_template.yaml,sha256=6iZDQH16WbBT2vNt3dhYStXr9H1x2agi_P32FjknuII,4290
177
+ sflow/samples/self_contained/slurm/auto_replica.yaml,sha256=YehFc8zdjgwQUjhZy_nwbswyWQiLYaiSxLdb-7XxT7E,5019
178
+ sflow/samples/self_contained/slurm/dynamo_sglang_agg.yaml,sha256=kDtGgGDaT2H_E6ajlvsmgvgJZ7egd3sQQCo-IBd5OrE,11156
179
+ sflow/samples/self_contained/slurm/dynamo_sglang_disagg.yaml,sha256=aQmQT3rykdQFcLalrq2bYAK_KYlaDciGE_nkfKL_8H8,15613
180
+ sflow/samples/self_contained/slurm/dynamo_trtllm_agg.yaml,sha256=dEvfDqlwCSVRNYAKl7qLDDkM8LexuYAKCz-6WNSA2-Q,11194
181
+ sflow/samples/self_contained/slurm/dynamo_trtllm_disagg.yaml,sha256=t0lxRw_fsMNjBqDCQVwUSi3dlpk_PHPEugMcHbFu44Q,15726
182
+ sflow/samples/self_contained/slurm/dynamo_vllm_agg.yaml,sha256=OBoC9h2YJa-ntaTv3S7Bg987QXnNozchoWgfTJhinys,12194
183
+ sflow/samples/self_contained/slurm/dynamo_vllm_disagg.yaml,sha256=nry9mymDmwes3iCECPJnMax3sqToCHvtyw6NR1zbC5U,18501
184
+ sflow/samples/self_contained/slurm/gpu_indices.yaml,sha256=22CND3SYKoNS5oevXWawuwmjVShg4mtD-Hgrvpvjb6c,4345
185
+ sflow/samples/self_contained/slurm/gpu_placement_matrix.yaml,sha256=oSeHFUrB7KMRb7sEDXuzANkVkds3xyB9OvwR9PK9Z9s,15153
186
+ sflow/samples/self_contained/slurm/infmax_v1_ds_r1.yaml,sha256=vrvytnVsMvvVEFg7UuJP5rJ2zHGylqkcNbEkVS2678E,15032
187
+ sflow/samples/self_contained/slurm/monitor_mixed.yaml,sha256=V9O7FLgUTmZwHdfYAhHBrCX1DYxiwt2GxQVm010Yf5Q,24871
188
+ sflow/samples/self_contained/slurm/multi_backend.yaml,sha256=VHII0Wzls78vC6yQOeklLB2J_3l_EVYFRp4YzFlxejk,3031
189
+ sflow/samples/self_contained/slurm/resource_release_after.yaml,sha256=Sbp6f2YhBMTp45cePtaZoI8bgDvFqYVy9QzX1zWShfU,4405
190
+ sflow/samples/self_contained/slurm/sglang_server_client.yaml,sha256=iptj21NGRhc4PKg6s-DI7Xo6CbQ3Y7SVu-lz4Tjm-v8,6689
191
+ sflow/samples/self_contained/slurm/trtllm_serve_disagg.yaml,sha256=9-0lG8j3K5htYQM9UvUAgKk0SywoQkomAHE5s8BGcTc,17301
192
+ sflow/skills/AGENTS.md,sha256=-NH7JambqD77Rei5bICCm7eMD8QG1xFScM5c6KdaHuM,7450
193
+ sflow/skills/__init__.py,sha256=jz6XAJLhBL9H0LidstV1AXiK1_5qo_pZpij_oRdHCFg,825
194
+ sflow/skills/sflow-code-review/SKILL.md,sha256=GBW34SdnUqtaqdzfKgkz2j9pNdW698XJY6CC3EVo_2k,13755
195
+ sflow/skills/sflow-code-review/reference.md,sha256=NcPlAcmNhFnia1mGX-c8fEoFk1R5dYm1uVVBGxhtpUA,8525
196
+ sflow/skills/sflow-error-analysis/SKILL.md,sha256=5A-hj5_8KnBOSm0N5k13dPWfSQQEkz771O1Tep_kneg,13257
197
+ sflow/skills/sflow-error-analysis/error-catalog.md,sha256=cewli7sCSyYm-Fzid6LM89qBPDl8K8nXViPLwqGF7Ug,24429
198
+ sflow/skills/sflow-error-analysis/scripts/parse_sflow_errors.py,sha256=MjbrHcaIzBxucDD7zz_POZydCXNCeAeHPRV_4JGv0hU,22260
199
+ sflow/skills/sflow-error-analysis/scripts/summarize_run.py,sha256=WdSF3SQokT4pyy15U9Je97LabyReMRQQOUOEENh_AUk,5891
200
+ sflow/skills/sflow-error-analysis/scripts/triage.py,sha256=uOnPVbAUx3vmzMrfXTYAbkuEtqu4NUSHrll7-PlnI_w,4794
201
+ sflow/skills/writing-sflow-yaml/SKILL.md,sha256=QE3kXtr5qMuf5VVhl_aEqajUpkSq9Rg_535Lg6vKvmg,16789
202
+ sflow/skills/writing-sflow-yaml/examples.md,sha256=EPWutRo7K1Jzu-wi7rvm4MCRUNQ7ybZvAvBYmU7-ero,27249
203
+ sflow/skills/writing-sflow-yaml/schema-reference.md,sha256=hIuWaHqwUbCnpd8Q_5fM-MWb9lGDF86ZSYyBZDPSeag,57382
204
+ sflow/skills/writing-sflow-yaml/scripts/check_gpu_plan.py,sha256=tsDqL4WXCPDy52o2lUIGVBZzeHSlEPp_sO2_KM1nFyc,12633
205
+ sflow/skills/writing-sflow-yaml/scripts/preflight.py,sha256=qzA1i1eidtYhlsRc80W7RWHaqwFTqx26Ya56zAfmC18,6011
206
+ sflow/skills/writing-sflow-yaml/scripts/validate_sflow_yaml.py,sha256=lHLm2fO_DQmDuYso5KwOcfH0jqF3F96yWB5TF-FsaOg,25096
207
+ sflow/ui/__init__.py,sha256=seLgGgbr4l8ev7M44fi4-3zma_Qf5RC6do6C3PkAyxU,246
208
+ sflow/ui/rich_tui.py,sha256=9XfFwDtMw6YB0K_wtbaS4tUgjZbIGxLDuRK9ebmVdAI,23125
209
+ sflow/utils/__init__.py,sha256=XLO09Ei8g0lU7hYlzKCvhvQhLFBe5CBwE4v2PqK9xWY,142
210
+ sflow/utils/console_text.py,sha256=AGVDovwagnztgFb2pQzUA8CGZ9HXgzutnsnJeBOdgXs,6787
211
+ sflow/utils/container.py,sha256=JRKmCK3z0lEOm9XuNYDdtFTLZl5CB76VGE0oDoiYI3s,7928
212
+ sflow/utils/extra_args.py,sha256=GbUbcKK7DryMPM9Jg8mIup1M9U3Ih3FyLV9Pug7xT0Q,3660
213
+ sflow/utils/gpu.py,sha256=mlUEyZGFkEsBS30w3pDyGgL1ieLN210rymf9nFqJC18,8502
214
+ sflow/utils/gpu_reservation.py,sha256=Px5tGB57nXskmkzN9SLvGLzECOGEygknI-hHidcVe_o,34146
215
+ sflow/utils/install.py,sha256=PCbT7r_RpR4P5Ylh8rfCLjssHP5dwsohHBZ6g3DrGYs,6623
216
+ sflow/utils/logging.py,sha256=cAE7R9s9Ezx-7nSonZa7GD1k1jZQSM2xl3eYXhh9bZg,8963
217
+ sflow/utils/node_filters.py,sha256=E9tnrFxUr9S8tATKv8l0yc1jQ9R397A5giYx7Pb1Xbw,4492
218
+ sflow/utils/parser.py,sha256=7WkH_ycHO_BtfYFsxGKJfqA6H6WBPOXBqloqrNBKCV8,3650
219
+ sflow/utils/script.py,sha256=zWHjVwdUGBBHHICiETKTecGf-TQvALIp1cmTXCFO6ZY,5093
220
+ sflow/utils/slurm.py,sha256=IZT2-ZNodV2cgMcUfgZqylHLGW6r0q15dB49Ux50pK4,1362
221
+ nv_sflow-0.3.1.dist-info/METADATA,sha256=JuDKLFEmz5t1mCFN9A6EX0NoeyGb4nXEfQoBZ4NAUNE,11331
222
+ nv_sflow-0.3.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
223
+ nv_sflow-0.3.1.dist-info/entry_points.txt,sha256=rb5FWurAAG_3SCRrllEXOoO-IIqJKXP2myut7gM2HTQ,40
224
+ nv_sflow-0.3.1.dist-info/top_level.txt,sha256=B9CtX8qufNaT90l8wPZUDYfiBfLR7Vs2LPAtCKtz3FA,6
225
+ nv_sflow-0.3.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sflow = sflow.cli:app