xoscar 0.9.0__cp312-cp312-macosx_10_13_x86_64.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 (94) hide show
  1. xoscar/__init__.py +61 -0
  2. xoscar/_utils.cpython-312-darwin.so +0 -0
  3. xoscar/_utils.pxd +36 -0
  4. xoscar/_utils.pyx +246 -0
  5. xoscar/_version.py +693 -0
  6. xoscar/aio/__init__.py +16 -0
  7. xoscar/aio/base.py +86 -0
  8. xoscar/aio/file.py +59 -0
  9. xoscar/aio/lru.py +228 -0
  10. xoscar/aio/parallelism.py +39 -0
  11. xoscar/api.py +527 -0
  12. xoscar/backend.py +67 -0
  13. xoscar/backends/__init__.py +14 -0
  14. xoscar/backends/allocate_strategy.py +160 -0
  15. xoscar/backends/communication/__init__.py +30 -0
  16. xoscar/backends/communication/base.py +315 -0
  17. xoscar/backends/communication/core.py +69 -0
  18. xoscar/backends/communication/dummy.py +253 -0
  19. xoscar/backends/communication/errors.py +20 -0
  20. xoscar/backends/communication/socket.py +444 -0
  21. xoscar/backends/communication/ucx.py +538 -0
  22. xoscar/backends/communication/utils.py +97 -0
  23. xoscar/backends/config.py +157 -0
  24. xoscar/backends/context.py +437 -0
  25. xoscar/backends/core.py +352 -0
  26. xoscar/backends/indigen/__init__.py +16 -0
  27. xoscar/backends/indigen/__main__.py +19 -0
  28. xoscar/backends/indigen/backend.py +51 -0
  29. xoscar/backends/indigen/driver.py +26 -0
  30. xoscar/backends/indigen/fate_sharing.py +221 -0
  31. xoscar/backends/indigen/pool.py +515 -0
  32. xoscar/backends/indigen/shared_memory.py +548 -0
  33. xoscar/backends/message.cpython-312-darwin.so +0 -0
  34. xoscar/backends/message.pyi +255 -0
  35. xoscar/backends/message.pyx +646 -0
  36. xoscar/backends/pool.py +1630 -0
  37. xoscar/backends/router.py +285 -0
  38. xoscar/backends/test/__init__.py +16 -0
  39. xoscar/backends/test/backend.py +38 -0
  40. xoscar/backends/test/pool.py +233 -0
  41. xoscar/batch.py +256 -0
  42. xoscar/collective/__init__.py +27 -0
  43. xoscar/collective/backend/__init__.py +13 -0
  44. xoscar/collective/backend/nccl_backend.py +160 -0
  45. xoscar/collective/common.py +102 -0
  46. xoscar/collective/core.py +737 -0
  47. xoscar/collective/process_group.py +687 -0
  48. xoscar/collective/utils.py +41 -0
  49. xoscar/collective/xoscar_pygloo.cpython-312-darwin.so +0 -0
  50. xoscar/collective/xoscar_pygloo.pyi +239 -0
  51. xoscar/constants.py +23 -0
  52. xoscar/context.cpython-312-darwin.so +0 -0
  53. xoscar/context.pxd +21 -0
  54. xoscar/context.pyx +368 -0
  55. xoscar/core.cpython-312-darwin.so +0 -0
  56. xoscar/core.pxd +51 -0
  57. xoscar/core.pyx +664 -0
  58. xoscar/debug.py +188 -0
  59. xoscar/driver.py +42 -0
  60. xoscar/errors.py +63 -0
  61. xoscar/libcpp.pxd +31 -0
  62. xoscar/metrics/__init__.py +21 -0
  63. xoscar/metrics/api.py +288 -0
  64. xoscar/metrics/backends/__init__.py +13 -0
  65. xoscar/metrics/backends/console/__init__.py +13 -0
  66. xoscar/metrics/backends/console/console_metric.py +82 -0
  67. xoscar/metrics/backends/metric.py +149 -0
  68. xoscar/metrics/backends/prometheus/__init__.py +13 -0
  69. xoscar/metrics/backends/prometheus/prometheus_metric.py +70 -0
  70. xoscar/nvutils.py +717 -0
  71. xoscar/profiling.py +260 -0
  72. xoscar/serialization/__init__.py +20 -0
  73. xoscar/serialization/aio.py +141 -0
  74. xoscar/serialization/core.cpython-312-darwin.so +0 -0
  75. xoscar/serialization/core.pxd +28 -0
  76. xoscar/serialization/core.pyi +57 -0
  77. xoscar/serialization/core.pyx +944 -0
  78. xoscar/serialization/cuda.py +111 -0
  79. xoscar/serialization/exception.py +48 -0
  80. xoscar/serialization/mlx.py +67 -0
  81. xoscar/serialization/numpy.py +82 -0
  82. xoscar/serialization/pyfury.py +37 -0
  83. xoscar/serialization/scipy.py +72 -0
  84. xoscar/serialization/torch.py +180 -0
  85. xoscar/utils.py +522 -0
  86. xoscar/virtualenv/__init__.py +34 -0
  87. xoscar/virtualenv/core.py +268 -0
  88. xoscar/virtualenv/platform.py +56 -0
  89. xoscar/virtualenv/utils.py +100 -0
  90. xoscar/virtualenv/uv.py +321 -0
  91. xoscar-0.9.0.dist-info/METADATA +230 -0
  92. xoscar-0.9.0.dist-info/RECORD +94 -0
  93. xoscar-0.9.0.dist-info/WHEEL +6 -0
  94. xoscar-0.9.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,82 @@
1
+ # Copyright 2022-2023 XProbe Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import logging
18
+ from typing import Dict, Optional, Tuple
19
+
20
+ from ..metric import (
21
+ AbstractCounter,
22
+ AbstractGauge,
23
+ AbstractHistogram,
24
+ AbstractMeter,
25
+ AbstractMetric,
26
+ )
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class SimpleMetric:
32
+ _value: int | float
33
+
34
+ def __init__(
35
+ self, name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None
36
+ ):
37
+ self._name = name
38
+ self._description = description
39
+ self._tag_keys = tag_keys
40
+ self._value = 0
41
+
42
+ def update(self, value: float = 1.0, tags: Optional[Dict[str, str]] = None):
43
+ self._value = value
44
+ logger.debug(
45
+ "Reporting metric with name: %s, description: %s, value: %s, tags: %s",
46
+ self._name,
47
+ self._description,
48
+ value,
49
+ tags,
50
+ )
51
+
52
+ @property
53
+ def value(self):
54
+ return self._value
55
+
56
+
57
+ class ConsoleMetricMixin(AbstractMetric):
58
+ @property
59
+ def value(self):
60
+ return self._metric.value
61
+
62
+ def _init(self):
63
+ self._metric = SimpleMetric(self._name, self._description, self._tag_keys)
64
+
65
+ def _record(self, value=1, tags: Optional[Dict[str, str]] = None):
66
+ self._metric.update(value, tags)
67
+
68
+
69
+ class Counter(ConsoleMetricMixin, AbstractCounter):
70
+ pass
71
+
72
+
73
+ class Gauge(ConsoleMetricMixin, AbstractGauge):
74
+ pass
75
+
76
+
77
+ class Meter(ConsoleMetricMixin, AbstractMeter):
78
+ pass
79
+
80
+
81
+ class Histogram(ConsoleMetricMixin, AbstractHistogram):
82
+ pass
@@ -0,0 +1,149 @@
1
+ # Copyright 2022-2023 XProbe Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import time
18
+ from abc import ABC
19
+ from typing import Dict, Optional, Tuple
20
+
21
+ _THRESHOLD = 2000
22
+ _RECORDED_INTERVAL_SECS = 1
23
+
24
+
25
+ class AbstractMetric(ABC):
26
+ """Base class of metrics."""
27
+
28
+ _type: str | None = None
29
+ _tag_keys: tuple[str] | tuple | None
30
+
31
+ def __init__(
32
+ self, name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None
33
+ ):
34
+ assert isinstance(name, str), "Argument name should be a str"
35
+ assert isinstance(description, str), "Argument description should be a str"
36
+ if tag_keys is not None:
37
+ assert isinstance(tag_keys, tuple) and all(
38
+ isinstance(tag, str) for tag in tag_keys
39
+ ), "Argument tag_keys should be a tuple and its elements should be str"
40
+ self._name = name
41
+ self._description = description
42
+ self._tag_keys = tag_keys or tuple()
43
+ self._init()
44
+
45
+ @property
46
+ def type(self):
47
+ return self._type
48
+
49
+ @property
50
+ def name(self):
51
+ return self._name
52
+
53
+ @property
54
+ def description(self):
55
+ return self._description
56
+
57
+ @property
58
+ def tag_keys(self):
59
+ return self._tag_keys
60
+
61
+ def _init(self):
62
+ """Some initialization in subclass."""
63
+ pass
64
+
65
+ def record(self, value=1, tags: Optional[Dict[str, str]] = None):
66
+ """A public method called by users."""
67
+ pass
68
+
69
+ def _record(self, value: float = 1.0, tags: Optional[Dict[str, str]] = None):
70
+ """An internal method called by record() and should be
71
+ implemented by different metric backends.
72
+ """
73
+ pass
74
+
75
+
76
+ class AbstractCounter(AbstractMetric):
77
+ """A counter records the counts of events."""
78
+
79
+ _type = "Counter"
80
+
81
+ def __init__(
82
+ self, name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None
83
+ ):
84
+ super().__init__(name, description, tag_keys)
85
+ self._count = 0
86
+
87
+ def record(self, value=1, tags: Optional[Dict[str, str]] = None):
88
+ self._count += value
89
+ self._record(self._count, tags)
90
+
91
+
92
+ class AbstractGauge(AbstractMetric):
93
+ """A gauge represents a single numerical value that can be
94
+ arbitrarily set.
95
+ """
96
+
97
+ _type = "Gauge"
98
+
99
+ def record(self, value=1, tags: Optional[Dict[str, str]] = None):
100
+ self._record(value, tags)
101
+
102
+
103
+ class AbstractMeter(AbstractMetric):
104
+ """A meter measures the rate at which a set of events occur."""
105
+
106
+ _type = "Meter"
107
+
108
+ def __init__(
109
+ self, name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None
110
+ ):
111
+ super().__init__(name, description, tag_keys)
112
+ self._count = 0
113
+ self._last_time = time.time()
114
+
115
+ def record(self, value=1, tags: Optional[Dict[str, str]] = None):
116
+ self._count += value
117
+ now = time.time()
118
+ past = max(now - self._last_time, 1e-9)
119
+ if self._count >= _THRESHOLD or past >= _RECORDED_INTERVAL_SECS:
120
+ qps = self._count / past
121
+ self._record(qps, tags)
122
+ self._last_time = now
123
+ self._count = 0
124
+
125
+
126
+ class AbstractHistogram(AbstractMetric):
127
+ """A histogram measures the distribution of values in a stream of data."""
128
+
129
+ _type = "Histogram"
130
+ _data: list
131
+
132
+ def __init__(
133
+ self, name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None
134
+ ):
135
+ super().__init__(name, description, tag_keys)
136
+ self._data = list()
137
+ self._last_time = time.time()
138
+
139
+ def record(self, value=1, tags: Optional[Dict[str, str]] = None):
140
+ self._data.append(value)
141
+ now = time.time()
142
+ if (
143
+ len(self._data) >= _THRESHOLD
144
+ or now - self._last_time >= _RECORDED_INTERVAL_SECS
145
+ ):
146
+ avg = sum(self._data) / len(self._data)
147
+ self._record(avg, tags)
148
+ self._data.clear()
149
+ self._last_time = now
@@ -0,0 +1,13 @@
1
+ # Copyright 2022-2023 XProbe Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -0,0 +1,70 @@
1
+ # Copyright 2022-2023 XProbe Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import os
16
+ import socket
17
+ from typing import Dict, Optional
18
+
19
+ from ....utils import lazy_import
20
+ from ..metric import (
21
+ AbstractCounter,
22
+ AbstractGauge,
23
+ AbstractHistogram,
24
+ AbstractMeter,
25
+ AbstractMetric,
26
+ )
27
+
28
+ pc = lazy_import("prometheus_client", rename="pc")
29
+
30
+
31
+ class PrometheusMetricMixin(AbstractMetric):
32
+ def _init(self):
33
+ # Prometheus metric name must match the regex `[a-zA-Z_:][a-zA-Z0-9_:]*`
34
+ # `.` is a common character in metrics, so here replace it with `:`
35
+ self._name = self._name.replace(".", ":")
36
+ self._tag_keys = self._tag_keys + (
37
+ "host",
38
+ "pid",
39
+ )
40
+ self._tags = {"host": socket.gethostname(), "pid": os.getpid()}
41
+ try:
42
+ self._metric = (
43
+ pc.Gauge(self._name, self._description, self._tag_keys) if pc else None
44
+ )
45
+ except ValueError: # pragma: no cover
46
+ self._metric = None
47
+
48
+ def _record(self, value=1, tags: Optional[Dict[str, str]] = None):
49
+ if self._metric:
50
+ if tags is not None:
51
+ tags.update(self._tags)
52
+ else:
53
+ tags = self._tags
54
+ self._metric.labels(**tags).set(value)
55
+
56
+
57
+ class Counter(PrometheusMetricMixin, AbstractCounter):
58
+ pass
59
+
60
+
61
+ class Gauge(PrometheusMetricMixin, AbstractGauge):
62
+ pass
63
+
64
+
65
+ class Meter(PrometheusMetricMixin, AbstractMeter):
66
+ pass
67
+
68
+
69
+ class Histogram(PrometheusMetricMixin, AbstractHistogram):
70
+ pass