maxframe 0.1.0b5__cp39-cp39-win32.whl → 1.0.0__cp39-cp39-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of maxframe might be problematic. Click here for more details.

Files changed (203) hide show
  1. maxframe/_utils.cp39-win32.pyd +0 -0
  2. maxframe/codegen.py +10 -4
  3. maxframe/config/config.py +68 -10
  4. maxframe/config/validators.py +42 -11
  5. maxframe/conftest.py +58 -14
  6. maxframe/core/__init__.py +2 -16
  7. maxframe/core/entity/__init__.py +1 -12
  8. maxframe/core/entity/executable.py +1 -1
  9. maxframe/core/entity/objects.py +46 -45
  10. maxframe/core/entity/output_types.py +0 -3
  11. maxframe/core/entity/tests/test_objects.py +43 -0
  12. maxframe/core/entity/tileables.py +5 -78
  13. maxframe/core/graph/__init__.py +2 -2
  14. maxframe/core/graph/builder/__init__.py +0 -1
  15. maxframe/core/graph/builder/base.py +5 -4
  16. maxframe/core/graph/builder/tileable.py +4 -4
  17. maxframe/core/graph/builder/utils.py +4 -8
  18. maxframe/core/graph/core.cp39-win32.pyd +0 -0
  19. maxframe/core/graph/core.pyx +4 -4
  20. maxframe/core/graph/entity.py +9 -33
  21. maxframe/core/operator/__init__.py +2 -9
  22. maxframe/core/operator/base.py +3 -5
  23. maxframe/core/operator/objects.py +0 -9
  24. maxframe/core/operator/utils.py +55 -0
  25. maxframe/dataframe/__init__.py +1 -1
  26. maxframe/dataframe/arithmetic/around.py +5 -17
  27. maxframe/dataframe/arithmetic/core.py +15 -7
  28. maxframe/dataframe/arithmetic/docstring.py +7 -33
  29. maxframe/dataframe/arithmetic/equal.py +4 -2
  30. maxframe/dataframe/arithmetic/greater.py +4 -2
  31. maxframe/dataframe/arithmetic/greater_equal.py +4 -2
  32. maxframe/dataframe/arithmetic/less.py +2 -2
  33. maxframe/dataframe/arithmetic/less_equal.py +4 -2
  34. maxframe/dataframe/arithmetic/not_equal.py +4 -2
  35. maxframe/dataframe/arithmetic/tests/test_arithmetic.py +39 -16
  36. maxframe/dataframe/core.py +31 -7
  37. maxframe/dataframe/datasource/date_range.py +2 -2
  38. maxframe/dataframe/datasource/read_odps_query.py +117 -23
  39. maxframe/dataframe/datasource/read_odps_table.py +6 -3
  40. maxframe/dataframe/datasource/tests/test_datasource.py +103 -8
  41. maxframe/dataframe/datastore/tests/test_to_odps.py +48 -0
  42. maxframe/dataframe/datastore/to_odps.py +28 -0
  43. maxframe/dataframe/extensions/__init__.py +5 -0
  44. maxframe/dataframe/extensions/flatjson.py +131 -0
  45. maxframe/dataframe/extensions/flatmap.py +317 -0
  46. maxframe/dataframe/extensions/reshuffle.py +1 -1
  47. maxframe/dataframe/extensions/tests/test_extensions.py +108 -3
  48. maxframe/dataframe/groupby/core.py +1 -1
  49. maxframe/dataframe/groupby/cum.py +0 -1
  50. maxframe/dataframe/groupby/fill.py +4 -1
  51. maxframe/dataframe/groupby/getitem.py +6 -0
  52. maxframe/dataframe/groupby/tests/test_groupby.py +5 -1
  53. maxframe/dataframe/groupby/transform.py +5 -1
  54. maxframe/dataframe/indexing/align.py +1 -1
  55. maxframe/dataframe/indexing/loc.py +6 -4
  56. maxframe/dataframe/indexing/rename.py +5 -28
  57. maxframe/dataframe/indexing/sample.py +0 -1
  58. maxframe/dataframe/indexing/set_index.py +68 -1
  59. maxframe/dataframe/initializer.py +11 -1
  60. maxframe/dataframe/merge/__init__.py +9 -1
  61. maxframe/dataframe/merge/concat.py +41 -31
  62. maxframe/dataframe/merge/merge.py +237 -3
  63. maxframe/dataframe/merge/tests/test_merge.py +126 -1
  64. maxframe/dataframe/misc/apply.py +5 -10
  65. maxframe/dataframe/misc/case_when.py +1 -1
  66. maxframe/dataframe/misc/describe.py +2 -2
  67. maxframe/dataframe/misc/drop_duplicates.py +8 -8
  68. maxframe/dataframe/misc/eval.py +4 -0
  69. maxframe/dataframe/misc/memory_usage.py +2 -2
  70. maxframe/dataframe/misc/pct_change.py +1 -83
  71. maxframe/dataframe/misc/tests/test_misc.py +33 -2
  72. maxframe/dataframe/misc/transform.py +1 -30
  73. maxframe/dataframe/misc/value_counts.py +4 -17
  74. maxframe/dataframe/missing/dropna.py +1 -1
  75. maxframe/dataframe/missing/fillna.py +5 -5
  76. maxframe/dataframe/operators.py +1 -17
  77. maxframe/dataframe/reduction/core.py +2 -2
  78. maxframe/dataframe/reduction/tests/test_reduction.py +2 -4
  79. maxframe/dataframe/sort/sort_values.py +1 -11
  80. maxframe/dataframe/statistics/corr.py +3 -3
  81. maxframe/dataframe/statistics/quantile.py +13 -19
  82. maxframe/dataframe/statistics/tests/test_statistics.py +4 -4
  83. maxframe/dataframe/tests/test_initializer.py +33 -2
  84. maxframe/dataframe/utils.py +26 -11
  85. maxframe/dataframe/window/expanding.py +5 -3
  86. maxframe/dataframe/window/tests/test_expanding.py +2 -2
  87. maxframe/errors.py +13 -0
  88. maxframe/extension.py +12 -0
  89. maxframe/io/__init__.py +13 -0
  90. maxframe/io/objects/__init__.py +24 -0
  91. maxframe/io/objects/core.py +140 -0
  92. maxframe/io/objects/tensor.py +76 -0
  93. maxframe/io/objects/tests/__init__.py +13 -0
  94. maxframe/io/objects/tests/test_object_io.py +97 -0
  95. maxframe/{odpsio → io/odpsio}/__init__.py +3 -1
  96. maxframe/{odpsio → io/odpsio}/arrow.py +42 -10
  97. maxframe/{odpsio → io/odpsio}/schema.py +38 -16
  98. maxframe/io/odpsio/tableio.py +719 -0
  99. maxframe/io/odpsio/tests/__init__.py +13 -0
  100. maxframe/{odpsio → io/odpsio}/tests/test_schema.py +59 -22
  101. maxframe/{odpsio → io/odpsio}/tests/test_tableio.py +50 -23
  102. maxframe/{odpsio → io/odpsio}/tests/test_volumeio.py +4 -6
  103. maxframe/io/odpsio/volumeio.py +63 -0
  104. maxframe/learn/contrib/__init__.py +3 -1
  105. maxframe/learn/contrib/graph/__init__.py +15 -0
  106. maxframe/learn/contrib/graph/connected_components.py +215 -0
  107. maxframe/learn/contrib/graph/tests/__init__.py +13 -0
  108. maxframe/learn/contrib/graph/tests/test_connected_components.py +53 -0
  109. maxframe/learn/contrib/llm/__init__.py +16 -0
  110. maxframe/learn/contrib/llm/core.py +54 -0
  111. maxframe/learn/contrib/llm/models/__init__.py +14 -0
  112. maxframe/learn/contrib/llm/models/dashscope.py +73 -0
  113. maxframe/learn/contrib/llm/multi_modal.py +42 -0
  114. maxframe/learn/contrib/llm/text.py +42 -0
  115. maxframe/learn/contrib/xgboost/classifier.py +26 -2
  116. maxframe/learn/contrib/xgboost/core.py +87 -2
  117. maxframe/learn/contrib/xgboost/dmatrix.py +3 -6
  118. maxframe/learn/contrib/xgboost/predict.py +29 -46
  119. maxframe/learn/contrib/xgboost/regressor.py +3 -10
  120. maxframe/learn/contrib/xgboost/train.py +29 -18
  121. maxframe/{core/operator/fuse.py → learn/core.py} +7 -10
  122. maxframe/lib/mmh3.cp39-win32.pyd +0 -0
  123. maxframe/lib/mmh3.pyi +43 -0
  124. maxframe/lib/sparse/tests/test_sparse.py +15 -15
  125. maxframe/lib/wrapped_pickle.py +2 -1
  126. maxframe/opcodes.py +8 -0
  127. maxframe/protocol.py +154 -27
  128. maxframe/remote/core.py +4 -8
  129. maxframe/serialization/__init__.py +1 -0
  130. maxframe/serialization/core.cp39-win32.pyd +0 -0
  131. maxframe/serialization/core.pxd +3 -0
  132. maxframe/serialization/core.pyi +3 -0
  133. maxframe/serialization/core.pyx +67 -26
  134. maxframe/serialization/exception.py +1 -1
  135. maxframe/serialization/pandas.py +52 -17
  136. maxframe/serialization/serializables/core.py +180 -15
  137. maxframe/serialization/serializables/field_type.py +4 -1
  138. maxframe/serialization/serializables/tests/test_serializable.py +54 -5
  139. maxframe/serialization/tests/test_serial.py +2 -1
  140. maxframe/session.py +9 -2
  141. maxframe/tensor/__init__.py +81 -2
  142. maxframe/tensor/arithmetic/isclose.py +1 -0
  143. maxframe/tensor/arithmetic/tests/test_arithmetic.py +22 -18
  144. maxframe/tensor/core.py +5 -136
  145. maxframe/tensor/datasource/array.py +3 -0
  146. maxframe/tensor/datasource/full.py +1 -1
  147. maxframe/tensor/datasource/tests/test_datasource.py +1 -1
  148. maxframe/tensor/indexing/flatnonzero.py +1 -1
  149. maxframe/tensor/indexing/getitem.py +2 -0
  150. maxframe/tensor/merge/__init__.py +2 -0
  151. maxframe/tensor/merge/concatenate.py +101 -0
  152. maxframe/tensor/merge/tests/test_merge.py +30 -1
  153. maxframe/tensor/merge/vstack.py +74 -0
  154. maxframe/tensor/{base → misc}/__init__.py +2 -0
  155. maxframe/tensor/{base → misc}/atleast_1d.py +1 -3
  156. maxframe/tensor/misc/atleast_2d.py +70 -0
  157. maxframe/tensor/misc/atleast_3d.py +85 -0
  158. maxframe/tensor/misc/tests/__init__.py +13 -0
  159. maxframe/tensor/{base → misc}/transpose.py +22 -18
  160. maxframe/tensor/{base → misc}/unique.py +3 -3
  161. maxframe/tensor/operators.py +1 -7
  162. maxframe/tensor/random/core.py +1 -1
  163. maxframe/tensor/reduction/count_nonzero.py +2 -1
  164. maxframe/tensor/reduction/mean.py +1 -0
  165. maxframe/tensor/reduction/nanmean.py +1 -0
  166. maxframe/tensor/reduction/nanvar.py +2 -0
  167. maxframe/tensor/reduction/tests/test_reduction.py +12 -1
  168. maxframe/tensor/reduction/var.py +2 -0
  169. maxframe/tensor/statistics/quantile.py +2 -2
  170. maxframe/tensor/utils.py +2 -22
  171. maxframe/tests/test_protocol.py +34 -0
  172. maxframe/tests/test_utils.py +0 -12
  173. maxframe/tests/utils.py +17 -2
  174. maxframe/typing_.py +4 -1
  175. maxframe/udf.py +8 -9
  176. maxframe/utils.py +106 -86
  177. {maxframe-0.1.0b5.dist-info → maxframe-1.0.0.dist-info}/METADATA +25 -25
  178. {maxframe-0.1.0b5.dist-info → maxframe-1.0.0.dist-info}/RECORD +197 -173
  179. {maxframe-0.1.0b5.dist-info → maxframe-1.0.0.dist-info}/WHEEL +1 -1
  180. maxframe_client/__init__.py +0 -1
  181. maxframe_client/clients/framedriver.py +4 -1
  182. maxframe_client/fetcher.py +81 -74
  183. maxframe_client/session/consts.py +3 -0
  184. maxframe_client/session/graph.py +8 -2
  185. maxframe_client/session/odps.py +194 -40
  186. maxframe_client/session/task.py +94 -39
  187. maxframe_client/tests/test_fetcher.py +21 -3
  188. maxframe_client/tests/test_session.py +109 -8
  189. maxframe/core/entity/chunks.py +0 -68
  190. maxframe/core/entity/fuse.py +0 -73
  191. maxframe/core/graph/builder/chunk.py +0 -430
  192. maxframe/odpsio/tableio.py +0 -322
  193. maxframe/odpsio/volumeio.py +0 -95
  194. maxframe_client/clients/spe.py +0 -104
  195. /maxframe/{odpsio → core/entity}/tests/__init__.py +0 -0
  196. /maxframe/{tensor/base → dataframe/datastore}/tests/__init__.py +0 -0
  197. /maxframe/{odpsio → io/odpsio}/tests/test_arrow.py +0 -0
  198. /maxframe/tensor/{base → misc}/astype.py +0 -0
  199. /maxframe/tensor/{base → misc}/broadcast_to.py +0 -0
  200. /maxframe/tensor/{base → misc}/ravel.py +0 -0
  201. /maxframe/tensor/{base/tests/test_base.py → misc/tests/test_misc.py} +0 -0
  202. /maxframe/tensor/{base → misc}/where.py +0 -0
  203. {maxframe-0.1.0b5.dist-info → maxframe-1.0.0.dist-info}/top_level.txt +0 -0
@@ -21,6 +21,7 @@ import pytest
21
21
 
22
22
  from ....core import EntityData
23
23
  from ....lib.wrapped_pickle import switch_unpickle
24
+ from ....utils import no_default
24
25
  from ... import deserialize, serialize
25
26
  from .. import (
26
27
  AnyField,
@@ -94,6 +95,11 @@ class MySimpleSerializable(Serializable):
94
95
  _ref_val = ReferenceField("ref_val", "MySimpleSerializable")
95
96
 
96
97
 
98
+ class MySubSerializable(MySimpleSerializable):
99
+ _m_int_val = Int64Field("m_int_val", default=250)
100
+ _m_str_val = StringField("m_str_val", default="SUB_STR")
101
+
102
+
97
103
  class MySerializable(Serializable):
98
104
  _id = IdentityField("id")
99
105
  _any_val = AnyField("any_val")
@@ -138,10 +144,11 @@ class MySerializable(Serializable):
138
144
  oneof1_val=f"{__name__}.MySerializable",
139
145
  oneof2_val=MySimpleSerializable,
140
146
  )
147
+ _no_default_val = Float64Field("no_default_val", default=no_default)
141
148
 
142
149
 
143
150
  @pytest.mark.parametrize("set_is_ci", [False, True], indirect=True)
144
- @switch_unpickle
151
+ @switch_unpickle(forbidden=False)
145
152
  def test_serializable(set_is_ci):
146
153
  my_serializable = MySerializable(
147
154
  _id="1",
@@ -165,7 +172,9 @@ def test_serializable(set_is_ci):
165
172
  _key_val=MyHasKey("aaa"),
166
173
  _ndarray_val=np.random.rand(4, 3),
167
174
  _datetime64_val=pd.Timestamp(123),
168
- _timedelta64_val=pd.Timedelta(days=1),
175
+ _timedelta64_val=pd.Timedelta(
176
+ days=1, seconds=123, microseconds=345, nanoseconds=132
177
+ ),
169
178
  _datatype_val=np.dtype(np.int32),
170
179
  _index_val=pd.Index([1, 2]),
171
180
  _series_val=pd.Series(["a", "b"]),
@@ -180,6 +189,7 @@ def test_serializable(set_is_ci):
180
189
  _dict_val={"a": b"bytes_value"},
181
190
  _ref_val=MySerializable(),
182
191
  _oneof_val=MySerializable(_id="2"),
192
+ _no_default_val=no_default,
183
193
  )
184
194
 
185
195
  header, buffers = serialize(my_serializable)
@@ -187,12 +197,51 @@ def test_serializable(set_is_ci):
187
197
  _assert_serializable_eq(my_serializable, my_serializable2)
188
198
 
189
199
 
200
+ @pytest.mark.parametrize("set_is_ci", [False, True], indirect=True)
201
+ @switch_unpickle
202
+ def test_compatible_serializable(set_is_ci):
203
+ global MySimpleSerializable, MySubSerializable
204
+
205
+ old_base, old_sub = MySimpleSerializable, MySubSerializable
206
+
207
+ try:
208
+ my_sub_serializable = MySubSerializable(
209
+ _id="id_val",
210
+ _list_val=["abcd", "wxyz"],
211
+ _ref_val=MyHasKey(),
212
+ _m_int_val=3412,
213
+ _m_str_val="dfgghj",
214
+ )
215
+ header, buffers = serialize(my_sub_serializable)
216
+
217
+ class MySimpleSerializable(Serializable):
218
+ _id = IdentityField("id")
219
+ _int_val = Int64Field("int_val", default=1000)
220
+ _list_val = ListField("list_val", default_factory=list)
221
+ _ref_val = ReferenceField("ref_val", "MySimpleSerializable")
222
+ _dict_val = DictField("dict_val")
223
+
224
+ class MySubSerializable(MySimpleSerializable):
225
+ _m_int_val = Int64Field("m_int_val", default=250)
226
+ _m_str_val = StringField("m_str_val", default="SUB_STR")
227
+
228
+ my_sub_serializable2 = deserialize(header, buffers)
229
+ assert type(my_sub_serializable) is not type(my_sub_serializable2)
230
+ _assert_serializable_eq(my_sub_serializable, my_sub_serializable2)
231
+ finally:
232
+ MySimpleSerializable, MySubSerializable = old_base, old_sub
233
+
234
+
190
235
  def _assert_serializable_eq(my_serializable, my_serializable2):
191
236
  for field_name, field in my_serializable._FIELDS.items():
192
- if not hasattr(my_serializable, field.tag):
237
+ if not hasattr(my_serializable, field.name):
193
238
  continue
194
239
  expect_value = getattr(my_serializable, field_name)
195
- actual_value = getattr(my_serializable2, field_name)
240
+ if expect_value is no_default:
241
+ assert not hasattr(my_serializable2, field.name)
242
+ continue
243
+ else:
244
+ actual_value = getattr(my_serializable2, field_name)
196
245
  if isinstance(expect_value, np.ndarray):
197
246
  np.testing.assert_array_equal(expect_value, actual_value)
198
247
  elif isinstance(expect_value, pd.DataFrame):
@@ -208,7 +257,7 @@ def _assert_serializable_eq(my_serializable, my_serializable2):
208
257
  elif callable(expect_value):
209
258
  assert expect_value(1) == actual_value(1)
210
259
  else:
211
- assert expect_value == actual_value
260
+ assert expect_value == actual_value, f"Field {field_name}"
212
261
 
213
262
 
214
263
  @pytest.mark.parametrize("set_is_ci", [True], indirect=True)
@@ -42,7 +42,7 @@ except ImportError:
42
42
  from ...lib.sparse import SparseMatrix
43
43
  from ...lib.wrapped_pickle import switch_unpickle
44
44
  from ...tests.utils import require_cudf, require_cupy
45
- from ...utils import lazy_import
45
+ from ...utils import lazy_import, no_default
46
46
  from .. import (
47
47
  PickleContainer,
48
48
  RemoteException,
@@ -90,6 +90,7 @@ class CustomNamedTuple(NamedTuple):
90
90
  pd.Timedelta(102.234154131),
91
91
  {"abc": 5.6, "def": [3.4], "gh": None, "ijk": {}},
92
92
  OrderedDict([("abcd", 5.6)]),
93
+ no_default,
93
94
  ],
94
95
  )
95
96
  @switch_unpickle
maxframe/session.py CHANGED
@@ -150,6 +150,10 @@ class AbstractSession(ABC):
150
150
  def session_id(self):
151
151
  return self._session_id
152
152
 
153
+ @property
154
+ def closed(self) -> bool:
155
+ return self._closed
156
+
153
157
  def __eq__(self, other):
154
158
  return (
155
159
  isinstance(other, AbstractSession)
@@ -1283,9 +1287,12 @@ def get_default_or_create(**kwargs):
1283
1287
  if session is None:
1284
1288
  # no session attached, try to create one
1285
1289
  warnings.warn(warning_msg)
1286
- session = new_session(
1287
- ODPS.from_global() or ODPS.from_environments(), **kwargs
1290
+ odps_entry = (
1291
+ kwargs.pop("odps_entry", None)
1292
+ or ODPS.from_global()
1293
+ or ODPS.from_environments()
1288
1294
  )
1295
+ session = new_session(odps_entry=odps_entry, **kwargs)
1289
1296
  session.as_default()
1290
1297
  if isinstance(session, IsolatedAsyncSession):
1291
1298
  session = SyncSession.from_isolated_session(session)
@@ -114,7 +114,6 @@ from .arithmetic import (
114
114
  )
115
115
  from .arithmetic import truediv as true_divide
116
116
  from .arithmetic import trunc
117
- from .base import broadcast_to, transpose, unique, where
118
117
  from .core import Tensor
119
118
  from .datasource import (
120
119
  arange,
@@ -143,7 +142,16 @@ from .indexing import (
143
142
  take,
144
143
  unravel_index,
145
144
  )
146
- from .merge import stack
145
+ from .merge import concatenate, stack, vstack
146
+ from .misc import (
147
+ atleast_1d,
148
+ atleast_2d,
149
+ atleast_3d,
150
+ broadcast_to,
151
+ transpose,
152
+ unique,
153
+ where,
154
+ )
147
155
  from .rechunk import rechunk
148
156
  from .reduction import (
149
157
  all,
@@ -180,4 +188,75 @@ from .reduction import std, sum, var
180
188
  from .reshape import reshape
181
189
  from .ufunc import ufunc
182
190
 
191
+ # isort: off
192
+ # noinspection PyUnresolvedReferences
193
+ from numpy import (
194
+ e,
195
+ errstate,
196
+ geterr,
197
+ inf,
198
+ nan,
199
+ newaxis,
200
+ pi,
201
+ seterr,
202
+ )
203
+
204
+ try:
205
+ from numpy.exceptions import AxisError
206
+ except ImportError:
207
+ from numpy import AxisError
208
+
209
+ NAN = nan
210
+ NINF = -inf
211
+ Inf = inf
212
+ NaN = nan
213
+
214
+ # import numpy types
215
+ # noinspection PyUnresolvedReferences
216
+ from numpy import (
217
+ bool_ as bool,
218
+ bytes_,
219
+ character,
220
+ complex64,
221
+ complex128,
222
+ complexfloating,
223
+ datetime64,
224
+ double,
225
+ dtype,
226
+ flexible,
227
+ float16,
228
+ float32,
229
+ float64,
230
+ floating,
231
+ generic,
232
+ inexact,
233
+ int8,
234
+ int16,
235
+ int32,
236
+ int64,
237
+ intc,
238
+ intp,
239
+ number,
240
+ integer,
241
+ object_ as object,
242
+ signedinteger,
243
+ timedelta64,
244
+ uint,
245
+ uint8,
246
+ uint16,
247
+ uint32,
248
+ uint64,
249
+ unsignedinteger,
250
+ void,
251
+ )
252
+
253
+ try:
254
+ from numpy import cfloat
255
+ except ImportError:
256
+ from numpy import cdouble as cfloat
257
+ try:
258
+ from numpy import str_ as unicode_
259
+ except ImportError:
260
+ from numpy import unicode_
261
+
183
262
  del fetch, ufunc
@@ -23,6 +23,7 @@ from .core import TensorBinOp
23
23
 
24
24
  class TensorIsclose(TensorBinOp):
25
25
  _op_type_ = opcodes.ISCLOSE
26
+ _func_name = "isclose"
26
27
 
27
28
  rtol = Float64Field("rtol", default=None)
28
29
  atol = Float64Field("atol", default=None)
@@ -17,26 +17,13 @@
17
17
  import numpy as np
18
18
  import pytest
19
19
 
20
+ from maxframe.tensor.arithmetic.core import TensorBinOp, TensorUnaryOp
21
+ from maxframe.utils import collect_leaf_operators
22
+
20
23
  from ....core import enter_mode
21
24
  from ...core import SparseTensor, Tensor
22
25
  from ...datasource import array, empty, ones, tensor
23
- from .. import (
24
- TensorAdd,
25
- TensorGreaterThan,
26
- TensorIsclose,
27
- TensorLog,
28
- TensorSubtract,
29
- add,
30
- around,
31
- cos,
32
- frexp,
33
- isclose,
34
- isfinite,
35
- log,
36
- negative,
37
- subtract,
38
- truediv,
39
- )
26
+ from .. import * # noqa: F401
40
27
 
41
28
 
42
29
  def test_add():
@@ -252,7 +239,7 @@ def test_compare():
252
239
 
253
240
  def test_frexp():
254
241
  t1 = ones((3, 4, 5), chunk_size=2)
255
- t2 = empty((3, 4, 5), dtype=np.float_, chunk_size=2)
242
+ t2 = empty((3, 4, 5), dtype=np.dtype(float), chunk_size=2)
256
243
  op_type = type(t1.op)
257
244
 
258
245
  o1, o2 = frexp(t1)
@@ -412,3 +399,20 @@ def test_build_mode():
412
399
 
413
400
  with enter_mode(build=True):
414
401
  assert t1 != 2
402
+
403
+
404
+ def test_unary_op_func_name():
405
+ # make sure all the unary op has defined the func name.
406
+
407
+ results = collect_leaf_operators(TensorUnaryOp)
408
+ for op_type in results:
409
+ assert hasattr(op_type, "_func_name")
410
+
411
+
412
+ def test_binary_op_func_name():
413
+ # make sure all the binary op has defined the func name.
414
+
415
+ results = collect_leaf_operators(TensorBinOp)
416
+ for op_type in results:
417
+ if op_type not in (TensorSetImag, TensorSetReal):
418
+ assert hasattr(op_type, "_func_name")
maxframe/tensor/core.py CHANGED
@@ -23,8 +23,6 @@ from typing import Any, Dict
23
23
  import numpy as np
24
24
 
25
25
  from ..core import (
26
- Chunk,
27
- ChunkData,
28
26
  HasShapeTileable,
29
27
  HasShapeTileableData,
30
28
  OutputType,
@@ -36,14 +34,9 @@ from ..core.entity.utils import refresh_tileable_shape
36
34
  from ..serialization.serializables import (
37
35
  AnyField,
38
36
  DataTypeField,
39
- EnumField,
40
- FieldTypes,
41
- ListField,
42
37
  Serializable,
43
38
  StringField,
44
- TupleField,
45
39
  )
46
- from ..utils import on_deserialize_shape, on_serialize_shape, skip_na_call
47
40
  from .utils import fetch_corner_data, get_chunk_slices
48
41
 
49
42
  logger = logging.getLogger(__name__)
@@ -56,134 +49,18 @@ class TensorOrder(Enum):
56
49
  F_ORDER = "F"
57
50
 
58
51
 
59
- class TensorChunkData(ChunkData):
60
- __slots__ = ()
61
- _no_copy_attrs_ = ChunkData._no_copy_attrs_ | {"dtype"}
62
- type_name = "Tensor"
63
-
64
- # required fields
65
- _shape = TupleField(
66
- "shape",
67
- FieldTypes.int64,
68
- on_serialize=on_serialize_shape,
69
- on_deserialize=on_deserialize_shape,
70
- )
71
- _order = EnumField("order", TensorOrder, FieldTypes.string)
72
- # optional fields
73
- _dtype = DataTypeField("dtype")
74
-
75
- def __init__(self, op=None, index=None, shape=None, dtype=None, order=None, **kw):
76
- if isinstance(order, str):
77
- order = getattr(TensorOrder, order)
78
- super().__init__(
79
- _op=op, _index=index, _shape=shape, _dtype=dtype, _order=order, **kw
80
- )
81
- if self.order is None and self.op is not None:
82
- if len(self.inputs) == 0:
83
- self._order = TensorOrder.C_ORDER
84
- elif all(
85
- hasattr(inp, "order") and inp.order == TensorOrder.F_ORDER
86
- for inp in self.inputs
87
- ):
88
- self._order = TensorOrder.F_ORDER
89
- else:
90
- self._order = TensorOrder.C_ORDER
91
-
92
- @property
93
- def params(self) -> Dict[str, Any]:
94
- # params return the properties which useful to rebuild a new chunk
95
- return {
96
- "shape": self.shape,
97
- "dtype": self.dtype,
98
- "order": self.order,
99
- "index": self.index,
100
- }
101
-
102
- @params.setter
103
- def params(self, new_params: Dict[str, Any]):
104
- params = new_params.copy()
105
- params.pop("index", None) # index not needed to update
106
- new_shape = params.pop("shape", None)
107
- if new_shape is not None:
108
- self._shape = new_shape
109
- dtype = params.pop("dtype", None)
110
- if dtype is not None:
111
- self._dtype = dtype
112
- order = params.pop("order", None)
113
- if order is not None:
114
- self._order = order
115
- if params: # pragma: no cover
116
- raise TypeError(f"Unknown params: {list(params)}")
117
-
118
- @classmethod
119
- def get_params_from_data(cls, data: np.ndarray) -> Dict[str, Any]:
120
- from .array_utils import is_cupy
121
-
122
- if not is_cupy(data):
123
- data = np.asarray(data)
124
- order = (
125
- TensorOrder.C_ORDER if data.flags["C_CONTIGUOUS"] else TensorOrder.F_ORDER
126
- )
127
- return {"shape": data.shape, "dtype": data.dtype, "order": order}
128
-
129
- def __len__(self):
130
- try:
131
- return self.shape[0]
132
- except IndexError:
133
- if is_build_mode():
134
- return 0
135
- raise TypeError("len() of unsized object")
136
-
137
- @property
138
- def shape(self):
139
- return getattr(self, "_shape", None)
140
-
141
- @property
142
- def ndim(self):
143
- return len(self.shape)
144
-
145
- @property
146
- def size(self):
147
- return np.prod(self.shape).item()
148
-
149
- @property
150
- def dtype(self):
151
- return getattr(self, "_dtype", None) or self.op.dtype
152
-
153
- @property
154
- def order(self):
155
- return getattr(self, "_order", None)
156
-
157
- @property
158
- def nbytes(self):
159
- return np.prod(self.shape) * self.dtype.itemsize
160
-
161
-
162
- class TensorChunk(Chunk):
163
- __slots__ = ()
164
- _allow_data_type_ = (TensorChunkData,)
165
- type_name = "Tensor"
166
-
167
- def __len__(self):
168
- return len(self._data)
169
-
170
-
171
52
  class TensorData(HasShapeTileableData, _ExecuteAndFetchMixin):
172
53
  __slots__ = ()
173
54
  type_name = "Tensor"
174
55
 
56
+ _legacy_deprecated_non_primitives = ["_chunks"]
57
+
175
58
  # required fields
176
59
  _order = StringField(
177
60
  "order", on_serialize=attrgetter("value"), on_deserialize=TensorOrder
178
61
  )
179
62
  # optional fields
180
63
  _dtype = DataTypeField("dtype")
181
- _chunks = ListField(
182
- "chunks",
183
- FieldTypes.reference(TensorChunkData),
184
- on_serialize=skip_na_call(lambda x: [it.data for it in x]),
185
- on_deserialize=skip_na_call(lambda x: [TensorChunk(it) for it in x]),
186
- )
187
64
 
188
65
  def __init__(
189
66
  self,
@@ -318,7 +195,7 @@ class TensorData(HasShapeTileableData, _ExecuteAndFetchMixin):
318
195
  return fromsparse(self, fill_value=fill_value)
319
196
 
320
197
  def transpose(self, *axes):
321
- from .base import transpose
198
+ from .misc import transpose
322
199
 
323
200
  if len(axes) == 1 and isinstance(axes[0], Iterable):
324
201
  axes = axes[0]
@@ -346,11 +223,6 @@ class TensorData(HasShapeTileableData, _ExecuteAndFetchMixin):
346
223
 
347
224
  return reshape(self, shape, order=order)
348
225
 
349
- def totiledb(self, uri, ctx=None, key=None, timestamp=None):
350
- from .datastore import totiledb
351
-
352
- return totiledb(uri, self, ctx=ctx, key=key, timestamp=timestamp)
353
-
354
226
  @staticmethod
355
227
  def from_dataframe(in_df):
356
228
  from .datasource import from_dataframe
@@ -526,9 +398,6 @@ class Tensor(HasShapeTileable):
526
398
  """
527
399
  return self._data.T
528
400
 
529
- def totiledb(self, uri, ctx=None, key=None, timestamp=None):
530
- return self._data.totiledb(uri, ctx=ctx, key=key, timestamp=timestamp)
531
-
532
401
  def copy(self, order="C"):
533
402
  return super().copy().astype(self.dtype, order=order, copy=False)
534
403
 
@@ -589,7 +458,7 @@ class Tensor(HasShapeTileable):
589
458
  array([('c', 1), ('a', 2)],
590
459
  dtype=[('x', '|S1'), ('y', '<i4')])
591
460
  """
592
- from .base import sort
461
+ from .misc import sort
593
462
 
594
463
  self._data = sort(
595
464
  self,
@@ -651,7 +520,7 @@ class Tensor(HasShapeTileable):
651
520
  >>> a.execute()
652
521
  array([1, 2, 3, 4])
653
522
  """
654
- from .base import partition
523
+ from .misc import partition
655
524
 
656
525
  self._data = partition(self, kth, axis=axis, kind=kind, order=order, **kw).data
657
526
 
@@ -53,6 +53,9 @@ class ArrayDataSource(TensorNoInput):
53
53
 
54
54
  super().__init__(data=data, dtype=dtype, gpu=gpu, **kw)
55
55
 
56
+ def get_data(self):
57
+ return self.data
58
+
56
59
 
57
60
  class CSRMatrixDataSource(TensorNoInput):
58
61
  """
@@ -89,7 +89,7 @@ def full(shape, fill_value, dtype=None, chunk_size=None, gpu=None, order="C"):
89
89
  """
90
90
  v = np.asarray(fill_value)
91
91
  if len(v.shape) > 0:
92
- from ..base import broadcast_to
92
+ from ..misc import broadcast_to
93
93
 
94
94
  return broadcast_to(
95
95
  tensor(v, dtype=dtype, chunk_size=chunk_size, gpu=gpu, order=order), shape
@@ -141,7 +141,7 @@ def test_zeros():
141
141
 
142
142
 
143
143
  def test_data_source():
144
- from ...base.broadcast_to import TensorBroadcastTo
144
+ from ...misc.broadcast_to import TensorBroadcastTo
145
145
 
146
146
  data = np.random.random((10, 3))
147
147
  t = tensor(data, chunk_size=2)
@@ -55,6 +55,6 @@ def flatnonzero(a):
55
55
  >>> x.ravel()[mt.flatnonzero(x)].execute() # TODO(jisheng): accomplish this after fancy indexing is supported
56
56
 
57
57
  """
58
- from ..base import ravel
58
+ from ..misc import ravel
59
59
 
60
60
  return nonzero(ravel(a))[0]
@@ -130,6 +130,8 @@ def _calc_order(a, index):
130
130
  continue
131
131
  elif isinstance(ind, slice):
132
132
  shape = a.shape[in_axis]
133
+ if shape is np.nan:
134
+ return TensorOrder.C_ORDER
133
135
  slc = ind.indices(shape)
134
136
  if slc[0] == 0 and slc[1] == shape and slc[2] == 1:
135
137
  continue
@@ -12,4 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from .concatenate import concatenate
15
16
  from .stack import stack
17
+ from .vstack import vstack
@@ -0,0 +1,101 @@
1
+ # Copyright 1999-2024 Alibaba Group Holding Ltd.
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
+ import numpy as np
15
+
16
+ from ... import opcodes
17
+ from ...serialization.serializables import Int32Field
18
+ from ..datasource import tensor as astensor
19
+ from ..operators import TensorOperator, TensorOperatorMixin
20
+ from ..utils import validate_axis
21
+
22
+
23
+ class TensorConcatenate(TensorOperator, TensorOperatorMixin):
24
+ _op_type_ = opcodes.CONCATENATE
25
+
26
+ axis = Int32Field("axis", default=0)
27
+
28
+ def __call__(self, tensors):
29
+ axis = self.axis
30
+ shape = _calc_concatenate_shape(tensors, axis)
31
+ shape[axis] = sum(t.shape[axis] for t in tensors)
32
+ return self.new_tensor(tensors, shape=tuple(shape))
33
+
34
+
35
+ def concatenate(tensors, axis=0):
36
+ """
37
+ Join a sequence of arrays along an existing axis.
38
+
39
+ Parameters
40
+ ----------
41
+ a1, a2, ... : sequence of array_like
42
+ The tensors must have the same shape, except in the dimension
43
+ corresponding to `axis` (the first, by default).
44
+ axis : int, optional
45
+ The axis along which the tensors will be joined. Default is 0.
46
+
47
+ Returns
48
+ -------
49
+ res : Tensor
50
+ The concatenated tensor.
51
+
52
+ See Also
53
+ --------
54
+ stack : Stack a sequence of tensors along a new axis.
55
+ vstack : Stack tensors in sequence vertically (row wise)
56
+
57
+ Examples
58
+ --------
59
+ >>> import maxframe.tensor as mt
60
+
61
+ >>> a = mt.array([[1, 2], [3, 4]])
62
+ >>> b = mt.array([[5, 6]])
63
+ >>> mt.concatenate((a, b), axis=0).execute()
64
+ array([[1, 2],
65
+ [3, 4],
66
+ [5, 6]])
67
+ >>> mt.concatenate((a, b.T), axis=1).execute()
68
+ array([[1, 2, 5],
69
+ [3, 4, 6]])
70
+
71
+ """
72
+ if axis is None:
73
+ axis = 0
74
+ tensors = [astensor(t) for t in tensors]
75
+ axis = validate_axis(tensors[0].ndim, axis)
76
+
77
+ if len(set(t.ndim for t in tensors)) != 1:
78
+ raise ValueError("all the input tensors must have same number of dimensions")
79
+
80
+ shapes = [t.shape[:axis] + t.shape[axis + 1 :] for t in tensors]
81
+ if len(set(shapes)) != 1:
82
+ raise ValueError(
83
+ "all the input tensor dimensions "
84
+ "except for the concatenation axis must match exactly"
85
+ )
86
+ shape = _calc_concatenate_shape(tensors, axis)
87
+ if any(np.isnan(s) for i, s in enumerate(shape) if i != axis):
88
+ raise ValueError("cannot concatenate tensor with unknown shape")
89
+
90
+ return _concatenate(tensors, axis)
91
+
92
+
93
+ def _concatenate(tensors, axis=0):
94
+ dtype = np.result_type(*(t.dtype for t in tensors))
95
+
96
+ op = TensorConcatenate(axis=axis, dtype=dtype)
97
+ return op(tensors)
98
+
99
+
100
+ def _calc_concatenate_shape(tensors, axis):
101
+ return [0 if i == axis else tensors[0].shape[i] for i in range(tensors[0].ndim)]