gpustack-runtime 0.2.0.post5__tar.gz → 0.2.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.
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.gitignore +1 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/PKG-INFO +1 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/_version.py +2 -2
- gpustack_runtime-0.2.2/gpustack_runtime/_version_appendix.py +1 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__types__.py +13 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/kuberentes.py +36 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__utils__.py +32 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/ascend.py +1 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyamdsmi/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pydcmi/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyixml/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pymtml/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pymxsml/__init__.py +12 -2
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pynvml/__init__.py +6 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyrocmsmi/__init__.py +6 -1
- gpustack_runtime-0.2.2/tests/gpustack_runtime/deployer/test_workload_status.py +117 -0
- gpustack_runtime-0.2.2/tests/gpustack_runtime/detector/test_detector_utils.py +170 -0
- gpustack_runtime-0.2.0.post5/gpustack_runtime/_version_appendix.py +0 -1
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.codespelldict +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.codespellrc +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.dockerignore +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.gitattributes +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.pre-commit-config.yaml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/.python-version +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/LICENSE +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/Makefile +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/README.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/deploy/manifests/docker-compose.yaml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/deploy/manifests/kubernetes.yaml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/index.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/modules/gpustack_runtime.deployer.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/modules/gpustack_runtime.detector.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/modules/gpustack_runtime.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/__main__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/_version.pyi +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/cmds/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/cmds/__types__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/cmds/deployer.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/cmds/detector.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/cmds/images.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__patches__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__utils__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__types__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__utils__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/amd.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/ascend.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/hygon.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/iluvatar.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/metax.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/thead.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/docker.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/k8s/devicemanager/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/podman.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__types__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/amd.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/cambricon.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/hygon.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/iluvatar.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/metax.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/mthreads.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/nvidia.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyamdgpu/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/libhgml.so +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/libuki.so +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhsa/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/thead.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/envs.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/logging.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/hatch.toml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/mkdocs.yml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/pack/Dockerfile +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/pack/Dockerfile.dummy +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/pyproject.toml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/pytest.ini +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/ruff.toml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_compare_versions.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_correct_runner_image.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_jsons.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_multiple_yamls.yaml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_json.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_load_yaml_or_json_single_yaml.yaml +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/fixtures/test_nginx_entrypoint.sh +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/deployer/test_utils.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/fixtures/__init__.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/README.md +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi300x.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_amd_mi308x.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_amd_rx7800xt.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_ascend_310p3.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_ascend_910b2.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_hygon_k100ai.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_metax_c500.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_gb10.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h100.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h100_mig.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_h200.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4080super.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx4090d.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_nvidia_rtx5090d.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/detect_output_thead_ppu.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi300x.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_amd_mi308x.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_amd_rx7800xt.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_ascend_310p3.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_ascend_910b2.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_hygon_k100ai.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_metax_c500.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_mthreads_s5000.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h100.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h100_mig.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_h200.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4080super.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx4090d.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_nvidia_rtx5090d.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/samples/topology_output_thead_ppu.json +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_amd.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_ascend.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_cambricon.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_hygon.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_iluvatar.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_metax.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_mthreads.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_nvidia.py +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/uv.lock +0 -0
- {gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/uv.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gpustack-runtime
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: GPUStack Runtime is library for detecting GPU resources and launching GPU workloads.
|
|
5
5
|
Project-URL: Homepage, https://github.com/gpustack/runtime
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/gpustack/gpustack/issues
|
|
@@ -27,8 +27,8 @@ version_tuple: VERSION_TUPLE
|
|
|
27
27
|
__commit_id__: COMMIT_ID
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
|
|
30
|
-
__version__ = version = '0.2.
|
|
31
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
30
|
+
__version__ = version = '0.2.2'
|
|
31
|
+
__version_tuple__ = version_tuple = (0, 2, 2)
|
|
32
32
|
try:
|
|
33
33
|
from ._version_appendix import git_commit
|
|
34
34
|
__commit_id__ = commit_id = git_commit
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
git_commit = "3ea35d7"
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__types__.py
RENAMED
|
@@ -1135,6 +1135,10 @@ class WorkloadStatus:
|
|
|
1135
1135
|
Namespace for the workload.
|
|
1136
1136
|
labels (dict[str, str] | None):
|
|
1137
1137
|
Labels for the workload.
|
|
1138
|
+
annotations (dict[str, str] | None):
|
|
1139
|
+
Annotations for the workload.
|
|
1140
|
+
state_message (str):
|
|
1141
|
+
Message accompanying the current state.
|
|
1138
1142
|
executable (list[WorkloadStatusOperation]):
|
|
1139
1143
|
The operation for the executable containers of the workload.
|
|
1140
1144
|
loggable (list[WorkloadStatusOperation]):
|
|
@@ -1161,6 +1165,15 @@ class WorkloadStatus:
|
|
|
1161
1165
|
"""
|
|
1162
1166
|
Labels for the workload.
|
|
1163
1167
|
"""
|
|
1168
|
+
annotations: dict[str, str] | None = field(default_factory=dict)
|
|
1169
|
+
"""
|
|
1170
|
+
Annotations for the workload.
|
|
1171
|
+
"""
|
|
1172
|
+
state_message: str = ""
|
|
1173
|
+
"""
|
|
1174
|
+
Message accompanying the current state, e.g. the Kubernetes Pod's
|
|
1175
|
+
status message on failure (such as a device-plugin admission rejection).
|
|
1176
|
+
"""
|
|
1164
1177
|
executable: list[WorkloadStatusOperation] | None = field(default_factory=list)
|
|
1165
1178
|
"""
|
|
1166
1179
|
The operation for the executable containers of the workload.
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/kuberentes.py
RENAMED
|
@@ -227,12 +227,18 @@ class KubernetesWorkloadStatus(WorkloadStatus):
|
|
|
227
227
|
for k, v in (k_pod.metadata.labels or {}).items()
|
|
228
228
|
if not k.startswith("runtime.gpustack.ai/")
|
|
229
229
|
}
|
|
230
|
+
annotations = {
|
|
231
|
+
k: v
|
|
232
|
+
for k, v in (k_pod.metadata.annotations or {}).items()
|
|
233
|
+
if not k.startswith("runtime.gpustack.ai/")
|
|
234
|
+
}
|
|
230
235
|
|
|
231
236
|
super().__init__(
|
|
232
237
|
name=name,
|
|
233
238
|
created_at=created_at,
|
|
234
239
|
namespace=k_pod.metadata.namespace,
|
|
235
240
|
labels=labels,
|
|
241
|
+
annotations=annotations,
|
|
236
242
|
**kwargs,
|
|
237
243
|
)
|
|
238
244
|
|
|
@@ -259,6 +265,11 @@ class KubernetesWorkloadStatus(WorkloadStatus):
|
|
|
259
265
|
self.loggable.append(op)
|
|
260
266
|
|
|
261
267
|
self.state = self.parse_state(k_pod)
|
|
268
|
+
if k_pod.status.message:
|
|
269
|
+
# Surface the Pod's status message, e.g. a device-plugin
|
|
270
|
+
# admission rejection ("UnexpectedAdmissionError: Allocate
|
|
271
|
+
# failed ...") on Failed Pods.
|
|
272
|
+
self.state_message = k_pod.status.message
|
|
262
273
|
|
|
263
274
|
|
|
264
275
|
_NAME = "kubernetes"
|
|
@@ -267,6 +278,29 @@ Name of the Kubernetes deployer.
|
|
|
267
278
|
"""
|
|
268
279
|
|
|
269
280
|
|
|
281
|
+
def _pin_pod_for_kueue(
|
|
282
|
+
pod: kubernetes.client.V1Pod,
|
|
283
|
+
node_name: str | None,
|
|
284
|
+
) -> None:
|
|
285
|
+
"""
|
|
286
|
+
Adjust node pinning for Kueue-gated Pods in place.
|
|
287
|
+
|
|
288
|
+
Kueue-gated Pods (queue label present) cannot set spec.nodeName:
|
|
289
|
+
the API forbids nodeName until all schedulingGates have been
|
|
290
|
+
cleared. Pin via nodeSelector instead; kube-scheduler places
|
|
291
|
+
the Pod on the same node once Kueue admits it.
|
|
292
|
+
"""
|
|
293
|
+
if not node_name:
|
|
294
|
+
return
|
|
295
|
+
if "kueue.x-k8s.io/queue-name" not in (pod.metadata.labels or {}):
|
|
296
|
+
return
|
|
297
|
+
pod.spec.node_name = None
|
|
298
|
+
pod.spec.node_selector = {
|
|
299
|
+
**(pod.spec.node_selector or {}),
|
|
300
|
+
"kubernetes.io/hostname": node_name,
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
270
304
|
class KubernetesDeployer(EndoscopicDeployer):
|
|
271
305
|
"""
|
|
272
306
|
Deployer implementation for Kubernetes.
|
|
@@ -1191,6 +1225,8 @@ class KubernetesDeployer(EndoscopicDeployer):
|
|
|
1191
1225
|
|
|
1192
1226
|
core_api = kubernetes.client.CoreV1Api(self._client)
|
|
1193
1227
|
try:
|
|
1228
|
+
_pin_pod_for_kueue(pod, self._node_name)
|
|
1229
|
+
|
|
1194
1230
|
pod = self._mutate_create_pod(pod)
|
|
1195
1231
|
if envs.GPUSTACK_RUNTIME_DEPLOY_PRINT_CONVERSION:
|
|
1196
1232
|
clogger.info(
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__utils__.py
RENAMED
|
@@ -16,6 +16,38 @@ from typing import Any
|
|
|
16
16
|
from gpustack_runtime import envs
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
def clone_exception(exc: BaseException) -> BaseException:
|
|
20
|
+
"""
|
|
21
|
+
Build a fresh copy of an exception, without its traceback or chaining state.
|
|
22
|
+
|
|
23
|
+
The detector library wrappers cache the init failure and re-raise it on every
|
|
24
|
+
subsequent call to fail fast. Re-raising the *same* object is a memory leak:
|
|
25
|
+
CPython appends a new frame to its ``__traceback__`` on each raise, and those
|
|
26
|
+
frames retain the caller's locals indefinitely (gpustack/gpustack#5342).
|
|
27
|
+
|
|
28
|
+
Cloning via ``BaseException.__new__`` preserves the original type and
|
|
29
|
+
attributes regardless of the class's constructor signature -- some binding
|
|
30
|
+
error types take an error code and leave ``args`` empty (e.g. amdsmi's
|
|
31
|
+
``AmdSmiLibraryException``), so ``type(exc)(*exc.args)`` cannot reconstruct them.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
exc:
|
|
35
|
+
The exception to clone.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
A fresh exception of the same type, carrying the same args and attributes
|
|
39
|
+
but no traceback or ``__cause__``/``__context__`` chain.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
clone = BaseException.__new__(type(exc))
|
|
43
|
+
clone.args = exc.args
|
|
44
|
+
# Copy instance state (custom attributes, and __notes__ if any live here too).
|
|
45
|
+
# Guard against exotic exception types that don't expose __dict__.
|
|
46
|
+
if hasattr(exc, "__dict__"):
|
|
47
|
+
clone.__dict__.update(exc.__dict__)
|
|
48
|
+
return clone
|
|
49
|
+
|
|
50
|
+
|
|
19
51
|
@dataclass
|
|
20
52
|
class PCIDevice:
|
|
21
53
|
address: str
|
|
@@ -32,7 +32,12 @@ try:
|
|
|
32
32
|
|
|
33
33
|
if _libInitialized:
|
|
34
34
|
if _libInitializedException is not None:
|
|
35
|
-
raise
|
|
35
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
36
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
37
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
38
|
+
from ..__utils__ import clone_exception
|
|
39
|
+
|
|
40
|
+
raise clone_exception(_libInitializedException) from None
|
|
36
41
|
return
|
|
37
42
|
|
|
38
43
|
try:
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pydcmi/__init__.py
RENAMED
|
@@ -780,7 +780,12 @@ def dcmi_init():
|
|
|
780
780
|
|
|
781
781
|
if _libInitialized:
|
|
782
782
|
if _libInitializedException is not None:
|
|
783
|
-
raise
|
|
783
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
784
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
785
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
786
|
+
from ..__utils__ import clone_exception
|
|
787
|
+
|
|
788
|
+
raise clone_exception(_libInitializedException) from None
|
|
784
789
|
return
|
|
785
790
|
|
|
786
791
|
try:
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/__init__.py
RENAMED
|
@@ -2380,7 +2380,12 @@ def hgmlInitWithFlags(flags):
|
|
|
2380
2380
|
|
|
2381
2381
|
if _libInitialized:
|
|
2382
2382
|
if _libInitializedException is not None:
|
|
2383
|
-
raise
|
|
2383
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
2384
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
2385
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
2386
|
+
from ..__utils__ import clone_exception
|
|
2387
|
+
|
|
2388
|
+
raise clone_exception(_libInitializedException) from None
|
|
2384
2389
|
return
|
|
2385
2390
|
|
|
2386
2391
|
try:
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyixml/__init__.py
RENAMED
|
@@ -2131,7 +2131,12 @@ def nvmlInitWithFlags(flags):
|
|
|
2131
2131
|
|
|
2132
2132
|
if _libInitialized:
|
|
2133
2133
|
if _libInitializedException is not None:
|
|
2134
|
-
raise
|
|
2134
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
2135
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
2136
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
2137
|
+
from ..__utils__ import clone_exception
|
|
2138
|
+
|
|
2139
|
+
raise clone_exception(_libInitializedException) from None
|
|
2135
2140
|
return
|
|
2136
2141
|
|
|
2137
2142
|
try:
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pymtml/__init__.py
RENAMED
|
@@ -15,7 +15,12 @@ def mtmlLibraryInit():
|
|
|
15
15
|
|
|
16
16
|
if _libInitialized:
|
|
17
17
|
if _libInitializedException is not None:
|
|
18
|
-
raise
|
|
18
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
19
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
20
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
21
|
+
from ..__utils__ import clone_exception
|
|
22
|
+
|
|
23
|
+
raise clone_exception(_libInitializedException) from None
|
|
19
24
|
return
|
|
20
25
|
|
|
21
26
|
try:
|
|
@@ -778,7 +778,12 @@ def mxSmlInit():
|
|
|
778
778
|
|
|
779
779
|
if _libInitialized:
|
|
780
780
|
if _libInitializedException is not None:
|
|
781
|
-
raise
|
|
781
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
782
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
783
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
784
|
+
from ..__utils__ import clone_exception
|
|
785
|
+
|
|
786
|
+
raise clone_exception(_libInitializedException) from None
|
|
782
787
|
return
|
|
783
788
|
|
|
784
789
|
try:
|
|
@@ -802,7 +807,12 @@ def mxSmlInitWithFlags(flags):
|
|
|
802
807
|
|
|
803
808
|
if _libInitialized:
|
|
804
809
|
if _libInitializedException is not None:
|
|
805
|
-
raise
|
|
810
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
811
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
812
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
813
|
+
from ..__utils__ import clone_exception
|
|
814
|
+
|
|
815
|
+
raise clone_exception(_libInitializedException) from None
|
|
806
816
|
return
|
|
807
817
|
|
|
808
818
|
try:
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pynvml/__init__.py
RENAMED
|
@@ -16,7 +16,12 @@ def nvmlInitWithFlags(flags):
|
|
|
16
16
|
|
|
17
17
|
if _libInitialized:
|
|
18
18
|
if _libInitializedException is not None:
|
|
19
|
-
raise
|
|
19
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
20
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
21
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
22
|
+
from ..__utils__ import clone_exception
|
|
23
|
+
|
|
24
|
+
raise clone_exception(_libInitializedException) from None
|
|
20
25
|
return
|
|
21
26
|
|
|
22
27
|
try:
|
|
@@ -180,7 +180,12 @@ def rsmi_init(flags=0):
|
|
|
180
180
|
|
|
181
181
|
if _libInitialized:
|
|
182
182
|
if _libInitializedException is not None:
|
|
183
|
-
raise
|
|
183
|
+
# Re-raise a fresh copy: re-raising the same cached exception object
|
|
184
|
+
# appends a traceback frame on every call, and those frames retain the
|
|
185
|
+
# caller's locals, leaking memory over time. See gpustack/gpustack#5342.
|
|
186
|
+
from ..__utils__ import clone_exception
|
|
187
|
+
|
|
188
|
+
raise clone_exception(_libInitializedException) from None
|
|
184
189
|
return
|
|
185
190
|
|
|
186
191
|
try:
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
|
|
3
|
+
import kubernetes.client
|
|
4
|
+
|
|
5
|
+
from gpustack_runtime.deployer.__types__ import WorkloadStatus
|
|
6
|
+
from gpustack_runtime.deployer.kuberentes import (
|
|
7
|
+
KubernetesWorkloadStatus,
|
|
8
|
+
_pin_pod_for_kueue,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _pod(annotations=None) -> kubernetes.client.V1Pod:
|
|
13
|
+
return kubernetes.client.V1Pod(
|
|
14
|
+
metadata=kubernetes.client.V1ObjectMeta(
|
|
15
|
+
name="gpustack-test",
|
|
16
|
+
namespace="default",
|
|
17
|
+
creation_timestamp=datetime(2026, 7, 29, 8, 0, 0, tzinfo=timezone.utc),
|
|
18
|
+
labels={"app": "test"},
|
|
19
|
+
annotations=annotations,
|
|
20
|
+
),
|
|
21
|
+
spec=kubernetes.client.V1PodSpec(
|
|
22
|
+
containers=[kubernetes.client.V1Container(name="run-0")],
|
|
23
|
+
),
|
|
24
|
+
status=kubernetes.client.V1PodStatus(phase="Pending"),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_kubernetes_workload_status_annotations():
|
|
29
|
+
status = KubernetesWorkloadStatus(
|
|
30
|
+
name="test",
|
|
31
|
+
k_pod=_pod(
|
|
32
|
+
annotations={
|
|
33
|
+
"device.gpustack.ai/accelerator.allocated": '{"run-0": {}}',
|
|
34
|
+
"runtime.gpustack.ai/component-run-0-name": "internal",
|
|
35
|
+
},
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
# Third-party annotations (e.g. device-plugin allocation) are surfaced,
|
|
39
|
+
# runtime-internal annotations are filtered out.
|
|
40
|
+
assert status.annotations == {
|
|
41
|
+
"device.gpustack.ai/accelerator.allocated": '{"run-0": {}}',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_kubernetes_workload_status_annotations_absent():
|
|
46
|
+
status = KubernetesWorkloadStatus(name="test", k_pod=_pod(annotations=None))
|
|
47
|
+
assert status.annotations == {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_workload_status_annotations_default_empty():
|
|
51
|
+
# Docker/Podman deployers don't populate annotations; the base default is empty.
|
|
52
|
+
status = WorkloadStatus(name="test", created_at="2026-07-29T08:00:00.000000Z")
|
|
53
|
+
assert status.annotations == {}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_workload_status_annotations_json_roundtrip():
|
|
57
|
+
status = KubernetesWorkloadStatus(
|
|
58
|
+
name="test",
|
|
59
|
+
k_pod=_pod(annotations={"device.gpustack.ai/accelerator.allocated": "{}"}),
|
|
60
|
+
)
|
|
61
|
+
restored = WorkloadStatus.from_json(status.to_json())
|
|
62
|
+
assert restored.annotations == status.annotations
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _pinning_pod(labels=None) -> kubernetes.client.V1Pod:
|
|
66
|
+
return kubernetes.client.V1Pod(
|
|
67
|
+
metadata=kubernetes.client.V1ObjectMeta(name="p", labels=labels or {}),
|
|
68
|
+
spec=kubernetes.client.V1PodSpec(
|
|
69
|
+
node_name="node-a",
|
|
70
|
+
containers=[kubernetes.client.V1Container(name="run-0")],
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_pin_pod_for_kueue_switches_to_node_selector():
|
|
76
|
+
pod = _pinning_pod(labels={"kueue.x-k8s.io/queue-name": "q"})
|
|
77
|
+
_pin_pod_for_kueue(pod, "node-a")
|
|
78
|
+
assert pod.spec.node_name is None
|
|
79
|
+
assert pod.spec.node_selector == {"kubernetes.io/hostname": "node-a"}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_pin_pod_for_kueue_merges_existing_node_selector():
|
|
83
|
+
pod = _pinning_pod(labels={"kueue.x-k8s.io/queue-name": "q"})
|
|
84
|
+
pod.spec.node_selector = {"disk": "ssd"}
|
|
85
|
+
_pin_pod_for_kueue(pod, "node-a")
|
|
86
|
+
assert pod.spec.node_selector == {
|
|
87
|
+
"disk": "ssd",
|
|
88
|
+
"kubernetes.io/hostname": "node-a",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_pin_pod_for_kueue_noop_without_queue_label():
|
|
93
|
+
pod = _pinning_pod()
|
|
94
|
+
_pin_pod_for_kueue(pod, "node-a")
|
|
95
|
+
assert pod.spec.node_name == "node-a"
|
|
96
|
+
assert pod.spec.node_selector is None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_pin_pod_for_kueue_noop_without_node_name():
|
|
100
|
+
pod = _pinning_pod(labels={"kueue.x-k8s.io/queue-name": "q"})
|
|
101
|
+
_pin_pod_for_kueue(pod, None)
|
|
102
|
+
assert pod.spec.node_name == "node-a"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_kubernetes_workload_status_state_message():
|
|
106
|
+
pod = _pod()
|
|
107
|
+
pod.status = kubernetes.client.V1PodStatus(
|
|
108
|
+
phase="Failed",
|
|
109
|
+
message="Allocate failed due to no enough GPU devices",
|
|
110
|
+
)
|
|
111
|
+
status = KubernetesWorkloadStatus(name="test", k_pod=pod)
|
|
112
|
+
assert status.state_message == "Allocate failed due to no enough GPU devices"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_kubernetes_workload_status_state_message_default():
|
|
116
|
+
status = KubernetesWorkloadStatus(name="test", k_pod=_pod())
|
|
117
|
+
assert status.state_message == ""
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import ClassVar
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from gpustack_runtime.detector.__utils__ import clone_exception
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# --------------------------------------------------------------------------- #
|
|
12
|
+
# Exception classes that mimic the real binding error types, to exercise the #
|
|
13
|
+
# constructor shapes clone_exception has to survive. #
|
|
14
|
+
# --------------------------------------------------------------------------- #
|
|
15
|
+
class RocmLikeError(Exception):
|
|
16
|
+
"""Custom __init__ that does NOT call super().__init__ (like ROCMSMIError)."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, value):
|
|
19
|
+
self.value = value
|
|
20
|
+
|
|
21
|
+
def __str__(self):
|
|
22
|
+
return f"rocm {self.value}"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DcmiLikeError(Exception):
|
|
26
|
+
"""Custom __new__(cls, value) that requires a positional arg (like DCMIError)."""
|
|
27
|
+
|
|
28
|
+
_mapping: ClassVar[dict] = {}
|
|
29
|
+
|
|
30
|
+
def __new__(cls, value):
|
|
31
|
+
target = DcmiLikeError._mapping.get(value, cls)
|
|
32
|
+
obj = Exception.__new__(target)
|
|
33
|
+
obj.value = value
|
|
34
|
+
return obj
|
|
35
|
+
|
|
36
|
+
def __str__(self):
|
|
37
|
+
return f"dcmi {self.value}"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AmdSmiLikeError(Exception):
|
|
41
|
+
"""super().__init__() with no args -> args == (); state lives in __dict__.
|
|
42
|
+
|
|
43
|
+
This is the case that `type(exc)(*exc.args)` CANNOT reconstruct.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self, err_code):
|
|
47
|
+
super().__init__()
|
|
48
|
+
self.err_code = err_code
|
|
49
|
+
self.err_info = f"info-{err_code}"
|
|
50
|
+
|
|
51
|
+
def __str__(self):
|
|
52
|
+
return f"Error code: {self.err_code} | {self.err_info}"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _tb_len(exc: BaseException) -> int:
|
|
56
|
+
n = 0
|
|
57
|
+
tb = exc.__traceback__
|
|
58
|
+
while tb:
|
|
59
|
+
n += 1
|
|
60
|
+
tb = tb.tb_next
|
|
61
|
+
return n
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
ALL_CASES = [
|
|
65
|
+
RocmLikeError(-99997),
|
|
66
|
+
DcmiLikeError(-8007),
|
|
67
|
+
AmdSmiLikeError(43),
|
|
68
|
+
ValueError("boom"),
|
|
69
|
+
RuntimeError("multi", "arg", 3),
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# --------------------------------------------------------------------------- #
|
|
74
|
+
# Correctness: the clone must be usable in place of the original. #
|
|
75
|
+
# --------------------------------------------------------------------------- #
|
|
76
|
+
def test_clone_preserves_type():
|
|
77
|
+
for exc in ALL_CASES:
|
|
78
|
+
clone = clone_exception(exc)
|
|
79
|
+
assert type(clone) is type(exc)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_clone_is_a_distinct_object():
|
|
83
|
+
for exc in ALL_CASES:
|
|
84
|
+
clone = clone_exception(exc)
|
|
85
|
+
assert clone is not exc
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_clone_preserves_args_and_attributes_and_str():
|
|
89
|
+
for exc in ALL_CASES:
|
|
90
|
+
clone = clone_exception(exc)
|
|
91
|
+
assert clone.args == exc.args
|
|
92
|
+
assert clone.__dict__ == exc.__dict__
|
|
93
|
+
# str() relies on the preserved state; it must render identically.
|
|
94
|
+
assert str(clone) == str(exc)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_clone_still_matches_except_clause():
|
|
98
|
+
# A caller doing `except RocmLikeError` must still catch the clone.
|
|
99
|
+
with pytest.raises(RocmLikeError) as info:
|
|
100
|
+
raise clone_exception(RocmLikeError(-1))
|
|
101
|
+
assert info.value.value == -1
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@pytest.mark.skipif(
|
|
105
|
+
sys.version_info < (3, 11),
|
|
106
|
+
reason="Exception.add_note() was added in Python 3.11",
|
|
107
|
+
)
|
|
108
|
+
def test_clone_preserves_notes():
|
|
109
|
+
# __notes__ (add_note, 3.11+) lives in __dict__, so it is carried over by
|
|
110
|
+
# the __dict__ copy without any special handling.
|
|
111
|
+
exc = ValueError("boom")
|
|
112
|
+
exc.add_note("first note")
|
|
113
|
+
exc.add_note("second note")
|
|
114
|
+
clone = clone_exception(exc)
|
|
115
|
+
assert clone.__notes__ == ["first note", "second note"]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_clone_handles_amdsmi_style_empty_args():
|
|
119
|
+
# The whole reason we don't use `type(exc)(*exc.args)`: it blows up here.
|
|
120
|
+
exc = AmdSmiLikeError(7)
|
|
121
|
+
assert exc.args == ()
|
|
122
|
+
clone = clone_exception(exc)
|
|
123
|
+
assert clone.err_code == 7
|
|
124
|
+
assert clone.err_info == "info-7"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# --------------------------------------------------------------------------- #
|
|
128
|
+
# The point of the helper: cloning + re-raising must NOT grow the cached #
|
|
129
|
+
# exception's traceback (this is the gpustack/gpustack#5342 regression). #
|
|
130
|
+
# --------------------------------------------------------------------------- #
|
|
131
|
+
def test_reraising_clones_does_not_grow_cached_traceback():
|
|
132
|
+
# Seed a traceback on the "cached" exception, like a first failed init.
|
|
133
|
+
with pytest.raises(RocmLikeError) as info:
|
|
134
|
+
raise RocmLikeError(-99997)
|
|
135
|
+
cached = info.value
|
|
136
|
+
|
|
137
|
+
baseline = _tb_len(cached)
|
|
138
|
+
|
|
139
|
+
raised = []
|
|
140
|
+
for _ in range(500):
|
|
141
|
+
with pytest.raises(RocmLikeError) as info:
|
|
142
|
+
raise clone_exception(cached) from None
|
|
143
|
+
raised.append(info.value)
|
|
144
|
+
|
|
145
|
+
# The cached object's traceback is untouched by the re-raises.
|
|
146
|
+
assert _tb_len(cached) == baseline
|
|
147
|
+
# Every raise produced a fresh object, never the cached one.
|
|
148
|
+
assert all(r is not cached for r in raised)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_contrast_reraising_same_object_would_grow_traceback():
|
|
152
|
+
# Demonstrates the bug the helper fixes: re-raising the SAME object grows
|
|
153
|
+
# its traceback unbounded. (Sanity check that our test measures the right
|
|
154
|
+
# thing; not testing clone_exception here.)
|
|
155
|
+
with pytest.raises(RocmLikeError) as info:
|
|
156
|
+
raise RocmLikeError(-99997)
|
|
157
|
+
cached = info.value
|
|
158
|
+
|
|
159
|
+
before = _tb_len(cached)
|
|
160
|
+
for _ in range(50):
|
|
161
|
+
with pytest.raises(RocmLikeError):
|
|
162
|
+
raise cached
|
|
163
|
+
assert _tb_len(cached) > before
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_clone_severs_cause_and_context_when_raised_from_none():
|
|
167
|
+
with pytest.raises(ValueError, match="x") as info:
|
|
168
|
+
raise clone_exception(ValueError("x")) from None
|
|
169
|
+
assert info.value.__cause__ is None
|
|
170
|
+
assert info.value.__suppress_context__ is True
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
git_commit = "94ebfdd"
|
|
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
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/deploy/manifests/docker-compose.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/modules/gpustack_runtime.deployer.md
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/docs/modules/gpustack_runtime.detector.md
RENAMED
|
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
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__init__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__patches__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/__utils__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__init__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__types__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/__utils__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/amd.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/ascend.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/hygon.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/iluvatar.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/metax.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/deployer/cdi/thead.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__init__.py
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/__types__.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/cambricon.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/iluvatar.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/mthreads.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/libhgml.so
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhgml/libuki.so
RENAMED
|
File without changes
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/gpustack_runtime/detector/pyhsa/__init__.py
RENAMED
|
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
|
|
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
|
{gpustack_runtime-0.2.0.post5 → gpustack_runtime-0.2.2}/tests/gpustack_runtime/detector/test_amd.py
RENAMED
|
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
|