metatensor-core 0.2.2__tar.gz → 0.2.3__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.
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/CMakeLists.txt +1 -1
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/PKG-INFO +1 -1
- metatensor_core-0.2.3/git_version_info +2 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_data/_array.py +2 -2
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_data/_dlpack.py +16 -11
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_labels.py +75 -46
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_tensor.py +76 -6
- metatensor_core-0.2.3/metatensor-core-cxx-0.2.3.tar.gz +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/PKG-INFO +1 -1
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/SOURCES.txt +1 -1
- metatensor_core-0.2.2/git_version_info +0 -2
- metatensor_core-0.2.2/metatensor-core-cxx-0.2.2.tar.gz +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/AUTHORS +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/LICENSE +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/MANIFEST.in +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/README.rst +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/__init__.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_block.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_c_api.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_c_lib.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_data/__init__.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_data/_extract.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_status.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/_version.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/io/__init__.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/io/_block.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/io/_labels.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/io/_tensor.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/io/_utils.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/learn.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/operations.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/torch.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor/utils.py +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/dependency_links.txt +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/not-zip-safe +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/requires.txt +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/top_level.txt +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/pyproject.toml +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/setup.cfg +0 -0
- {metatensor_core-0.2.2 → metatensor_core-0.2.3}/setup.py +0 -0
|
@@ -14,7 +14,7 @@ set(METATENSOR_CORE_SOURCE_DIR "" CACHE PATH "Path to the sources of metatensor-
|
|
|
14
14
|
|
|
15
15
|
file(REMOVE ${CMAKE_INSTALL_PREFIX}/_external.py)
|
|
16
16
|
|
|
17
|
-
set(REQUIRED_METATENSOR_VERSION "0.2.
|
|
17
|
+
set(REQUIRED_METATENSOR_VERSION "0.2.3")
|
|
18
18
|
if(${METATENSOR_CORE_PYTHON_USE_EXTERNAL_LIB})
|
|
19
19
|
# when building a source checkout, update version to include git information
|
|
20
20
|
# this will not apply when building a sdist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metatensor-core
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python bindings for metatensor
|
|
5
5
|
Author: Guillaume Fraux, Rohit Goswami, Philip Loche, Filippo Bigi, Joseph W. Abbott, Davide Tisi, Alexander Goscinski, Michele Ceriotti
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -37,9 +37,9 @@ except ImportError:
|
|
|
37
37
|
if HAS_TORCH:
|
|
38
38
|
# This NewType is only used for typechecking and documentation purposes. If you are
|
|
39
39
|
# trying to add support for new array types, see `data.array.ArrayWrapper` instead.
|
|
40
|
-
Array = NewType("Array", Union[np.ndarray, torch.Tensor])
|
|
40
|
+
Array = NewType("Array", Union[np.ndarray, torch.Tensor, mts_array_t])
|
|
41
41
|
else:
|
|
42
|
-
Array = NewType("Array", np.ndarray)
|
|
42
|
+
Array = NewType("Array", Union[np.ndarray, mts_array_t])
|
|
43
43
|
|
|
44
44
|
Array.__doc__ = """
|
|
45
45
|
An ``Array`` contains the actual data stored in a :py:class:`metatensor.TensorBlock`.
|
|
@@ -264,16 +264,6 @@ class DLPackArray:
|
|
|
264
264
|
if stream is not None:
|
|
265
265
|
raise RuntimeError("only `stream=None` is supported")
|
|
266
266
|
|
|
267
|
-
if self._versioned:
|
|
268
|
-
version = pointer[0].version
|
|
269
|
-
version = (version.major, version.minor)
|
|
270
|
-
if max_version is not None:
|
|
271
|
-
if version[0] > max_version[0]:
|
|
272
|
-
raise RuntimeError(
|
|
273
|
-
f"requested DLPack version {max_version}, but tensor has "
|
|
274
|
-
f"version {version}"
|
|
275
|
-
)
|
|
276
|
-
|
|
277
267
|
if dl_device is not None and dl_device != self.__dlpack_device__():
|
|
278
268
|
raise RuntimeError("device conversion is not supported")
|
|
279
269
|
|
|
@@ -282,7 +272,22 @@ class DLPackArray:
|
|
|
282
272
|
|
|
283
273
|
self._pointer = None
|
|
284
274
|
if self._versioned:
|
|
285
|
-
|
|
275
|
+
version = pointer[0].version
|
|
276
|
+
version_tuple = (version.major, version.minor)
|
|
277
|
+
|
|
278
|
+
if max_version is not None and version_tuple[0] > max_version[0]:
|
|
279
|
+
raise RuntimeError(
|
|
280
|
+
f"requested DLPack version {max_version}, but tensor has "
|
|
281
|
+
f"version {version_tuple}"
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
if max_version is not None and max_version >= (1, 0):
|
|
285
|
+
capsule = make_dlpack_versioned_capsule(pointer)
|
|
286
|
+
else:
|
|
287
|
+
# Consumer doesn't signal DLPack v1 support (e.g. PyTorch < 2.9.0),
|
|
288
|
+
# wrap as unversioned for compatibility
|
|
289
|
+
unversioned_ptr = wrap_versioned_as_unversioned(pointer)
|
|
290
|
+
capsule = make_dlpack_unversioned_capsule(unversioned_ptr)
|
|
286
291
|
else:
|
|
287
292
|
capsule = make_dlpack_unversioned_capsule(pointer)
|
|
288
293
|
|
|
@@ -8,13 +8,15 @@ import numpy as np
|
|
|
8
8
|
|
|
9
9
|
from . import _data
|
|
10
10
|
from ._c_api import (
|
|
11
|
+
DLDataType,
|
|
12
|
+
DLDataTypeCode,
|
|
11
13
|
c_uintptr_t,
|
|
12
14
|
mts_array_t,
|
|
13
15
|
mts_labels_t,
|
|
14
16
|
)
|
|
15
17
|
from ._c_lib import _get_library
|
|
16
18
|
from ._data import Array, Device
|
|
17
|
-
from ._status import check_pointer
|
|
19
|
+
from ._status import check_pointer, check_status
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
try:
|
|
@@ -138,6 +140,72 @@ class LabelsEntry:
|
|
|
138
140
|
return not self.__eq__(other)
|
|
139
141
|
|
|
140
142
|
|
|
143
|
+
def _labels_values_mts_array(array: Array, size: int) -> (mts_array_t, Array):
|
|
144
|
+
if isinstance(array, mts_array_t):
|
|
145
|
+
shape_ptr = ctypes.POINTER(c_uintptr_t)()
|
|
146
|
+
shape_count = c_uintptr_t()
|
|
147
|
+
check_status(
|
|
148
|
+
array.shape(array.ptr, ctypes.byref(shape_ptr), ctypes.byref(shape_count))
|
|
149
|
+
)
|
|
150
|
+
shape = [shape_ptr[i] for i in range(shape_count.value)]
|
|
151
|
+
|
|
152
|
+
if len(shape) != 2:
|
|
153
|
+
raise ValueError("`values` must be a 2D array")
|
|
154
|
+
|
|
155
|
+
if shape[1] != size:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
"`names` must have an entry for each column of the `values` array"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
dtype = DLDataType()
|
|
161
|
+
check_status(array.dtype(array.ptr, ctypes.byref(dtype)))
|
|
162
|
+
if dtype.code != DLDataTypeCode.kDLInt or dtype.bits != 32 or dtype.lanes != 1:
|
|
163
|
+
raise TypeError("Labels values must be of dtype int32")
|
|
164
|
+
|
|
165
|
+
return array, None
|
|
166
|
+
else:
|
|
167
|
+
values = array
|
|
168
|
+
backend = _data.array_backend(values)
|
|
169
|
+
|
|
170
|
+
if len(values) == 0:
|
|
171
|
+
# Explicitly define empty labels
|
|
172
|
+
values = np.empty((0, size), dtype=np.int32)
|
|
173
|
+
values = _data.array_change_backend(values, backend)
|
|
174
|
+
|
|
175
|
+
if len(values.shape) != 2:
|
|
176
|
+
# make sure the array is 2D
|
|
177
|
+
raise ValueError("`values` must be a 2D array")
|
|
178
|
+
|
|
179
|
+
if values.shape[1] != size:
|
|
180
|
+
raise ValueError(
|
|
181
|
+
"`names` must have an entry for each column of the `values` array"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if backend == "numpy":
|
|
185
|
+
try:
|
|
186
|
+
# We need to make sure the data has the right type
|
|
187
|
+
values = values.astype(
|
|
188
|
+
np.int32,
|
|
189
|
+
casting="same_kind",
|
|
190
|
+
subok=False,
|
|
191
|
+
copy=False,
|
|
192
|
+
)
|
|
193
|
+
# values should not be writeable
|
|
194
|
+
values.flags.writeable = False
|
|
195
|
+
except TypeError as e:
|
|
196
|
+
raise TypeError("Labels values must be convertible to integers") from e
|
|
197
|
+
elif backend == "torch":
|
|
198
|
+
if values.requires_grad:
|
|
199
|
+
raise ValueError("Labels values can not require gradients")
|
|
200
|
+
|
|
201
|
+
if not _data.array_dtype_is_integer(values):
|
|
202
|
+
raise TypeError("Labels values must be of integer dtype")
|
|
203
|
+
|
|
204
|
+
values = values.to(dtype=torch.int32, copy=False)
|
|
205
|
+
|
|
206
|
+
return _data.create_mts_array(values), values
|
|
207
|
+
|
|
208
|
+
|
|
141
209
|
class Labels:
|
|
142
210
|
"""
|
|
143
211
|
A set of labels carrying metadata associated with a :py:class:`TensorMap`.
|
|
@@ -213,7 +281,7 @@ class Labels:
|
|
|
213
281
|
def __init__(
|
|
214
282
|
self,
|
|
215
283
|
names: Union[str, Sequence[str]],
|
|
216
|
-
values:
|
|
284
|
+
values: Array,
|
|
217
285
|
assume_unique: bool = False,
|
|
218
286
|
):
|
|
219
287
|
"""
|
|
@@ -227,59 +295,20 @@ class Labels:
|
|
|
227
295
|
either by construction or because you checked.
|
|
228
296
|
"""
|
|
229
297
|
|
|
230
|
-
names = _normalize_names_type(names)
|
|
231
|
-
|
|
232
298
|
if not isinstance(values, Array.__supertype__):
|
|
233
|
-
raise ValueError("`values` must be a numpy ndarray or torch tensor")
|
|
234
|
-
|
|
235
|
-
backend = _data.array_backend(values)
|
|
236
|
-
|
|
237
|
-
if len(values) == 0:
|
|
238
|
-
# Explicitly define empty labels
|
|
239
|
-
values = np.empty((0, len(names)), dtype=np.int32)
|
|
240
|
-
values = _data.array_change_backend(values, backend)
|
|
241
|
-
|
|
242
|
-
if len(values.shape) != 2:
|
|
243
|
-
# make sure the array is 2D
|
|
244
|
-
raise ValueError("`values` must be a 2D array")
|
|
245
|
-
|
|
246
|
-
if len(names) != values.shape[1]:
|
|
247
299
|
raise ValueError(
|
|
248
|
-
"`
|
|
300
|
+
"`values` must be a numpy ndarray, torch tensor, or mts_array_t, "
|
|
301
|
+
f"got {type(values)}"
|
|
249
302
|
)
|
|
250
303
|
|
|
251
|
-
|
|
252
|
-
try:
|
|
253
|
-
# We need to make sure the data has the right type
|
|
254
|
-
values = values.astype(
|
|
255
|
-
np.int32,
|
|
256
|
-
casting="same_kind",
|
|
257
|
-
subok=False,
|
|
258
|
-
copy=False,
|
|
259
|
-
)
|
|
260
|
-
# values should not be writeable
|
|
261
|
-
values.flags.writeable = False
|
|
262
|
-
except TypeError as e:
|
|
263
|
-
raise TypeError("Labels values must be convertible to integers") from e
|
|
264
|
-
elif backend == "torch":
|
|
265
|
-
if values.requires_grad:
|
|
266
|
-
raise ValueError("Labels values can not require gradients")
|
|
267
|
-
|
|
268
|
-
if not _data.array_dtype_is_integer(values):
|
|
269
|
-
raise TypeError("Labels values must be of integer dtype")
|
|
270
|
-
|
|
271
|
-
values = values.to(dtype=torch.int32, copy=False)
|
|
272
|
-
|
|
273
|
-
if values.ndim == 1:
|
|
274
|
-
values = values.reshape(-1, len(names))
|
|
275
|
-
|
|
304
|
+
names = _normalize_names_type(names)
|
|
276
305
|
self._lib = _get_library()
|
|
306
|
+
array, values = _labels_values_mts_array(values, len(names))
|
|
307
|
+
|
|
277
308
|
c_names = ctypes.ARRAY(ctypes.c_char_p, len(names))()
|
|
278
309
|
for i, n in enumerate(names):
|
|
279
310
|
c_names[i] = n.encode("utf8")
|
|
280
311
|
|
|
281
|
-
array = _data.create_mts_array(values)
|
|
282
|
-
|
|
283
312
|
if assume_unique:
|
|
284
313
|
ptr = self._lib.mts_labels_assume_unique(c_names, len(names), array)
|
|
285
314
|
else:
|
|
@@ -7,11 +7,20 @@ import numpy as np
|
|
|
7
7
|
|
|
8
8
|
from . import _data
|
|
9
9
|
from ._block import TensorBlock
|
|
10
|
-
from ._c_api import
|
|
10
|
+
from ._c_api import (
|
|
11
|
+
DLDevice,
|
|
12
|
+
DLDeviceType,
|
|
13
|
+
DLManagedTensorVersioned,
|
|
14
|
+
DLPackVersion,
|
|
15
|
+
c_uintptr_t,
|
|
16
|
+
mts_array_t,
|
|
17
|
+
mts_block_t,
|
|
18
|
+
mts_tensormap_t,
|
|
19
|
+
)
|
|
11
20
|
from ._c_lib import _get_library
|
|
12
21
|
from ._data import Device, DType
|
|
13
22
|
from ._labels import Labels, LabelsEntry
|
|
14
|
-
from ._status import check_pointer
|
|
23
|
+
from ._status import check_pointer, check_status
|
|
15
24
|
|
|
16
25
|
|
|
17
26
|
class TensorMap:
|
|
@@ -417,7 +426,7 @@ class TensorMap:
|
|
|
417
426
|
elif isinstance(selection, int):
|
|
418
427
|
return self.block_by_id(selection)
|
|
419
428
|
else:
|
|
420
|
-
selection = _normalize_selection(selection)
|
|
429
|
+
selection = _normalize_selection(selection, like=self.keys)
|
|
421
430
|
|
|
422
431
|
keys = self.keys
|
|
423
432
|
matching = keys.select(selection)
|
|
@@ -471,7 +480,7 @@ class TensorMap:
|
|
|
471
480
|
elif isinstance(selection, int):
|
|
472
481
|
return [self.block_by_id(selection)]
|
|
473
482
|
else:
|
|
474
|
-
selection = _normalize_selection(selection)
|
|
483
|
+
selection = _normalize_selection(selection, like=self.keys)
|
|
475
484
|
|
|
476
485
|
keys = self.keys
|
|
477
486
|
matching = keys.select(selection)
|
|
@@ -833,8 +842,69 @@ def _can_cast_to_numpy_int(value):
|
|
|
833
842
|
return np.can_cast(value, np.int32, casting="same_kind")
|
|
834
843
|
|
|
835
844
|
|
|
845
|
+
def _array_like(values: List[int], like: Labels) -> mts_array_t:
|
|
846
|
+
"""
|
|
847
|
+
Convert a list of integers to an array with the same dtype, device and array backend
|
|
848
|
+
as ``like``.
|
|
849
|
+
|
|
850
|
+
:param values: list of integers to convert
|
|
851
|
+
:param like: Labels whose array backend and device to match
|
|
852
|
+
:return: a new ``mts_array_t`` with the same dtype, device and array backend as
|
|
853
|
+
``like``
|
|
854
|
+
"""
|
|
855
|
+
np_values = np.array(values, dtype=np.int32).reshape(1, -1)
|
|
856
|
+
cpu_array = _data.create_mts_array(np_values)
|
|
857
|
+
|
|
858
|
+
try:
|
|
859
|
+
like_array = like._raw_values
|
|
860
|
+
|
|
861
|
+
dl_managed_ptr = ctypes.POINTER(DLManagedTensorVersioned)()
|
|
862
|
+
device = DLDevice(device_type=DLDeviceType.kDLCPU, device_id=0)
|
|
863
|
+
version = DLPackVersion(major=1, minor=0)
|
|
864
|
+
status = cpu_array.as_dlpack(
|
|
865
|
+
cpu_array.ptr,
|
|
866
|
+
ctypes.byref(dl_managed_ptr),
|
|
867
|
+
device,
|
|
868
|
+
None,
|
|
869
|
+
version,
|
|
870
|
+
)
|
|
871
|
+
check_status(status)
|
|
872
|
+
|
|
873
|
+
result_array = mts_array_t()
|
|
874
|
+
status = like_array.from_dlpack(
|
|
875
|
+
like_array.ptr,
|
|
876
|
+
dl_managed_ptr,
|
|
877
|
+
ctypes.byref(result_array),
|
|
878
|
+
)
|
|
879
|
+
check_status(status)
|
|
880
|
+
|
|
881
|
+
target_device = DLDevice()
|
|
882
|
+
status = like_array.device(like_array.ptr, ctypes.byref(target_device))
|
|
883
|
+
check_status(status)
|
|
884
|
+
|
|
885
|
+
if target_device.device_type != DLDeviceType.kDLCPU:
|
|
886
|
+
device_array = mts_array_t()
|
|
887
|
+
status = result_array.copy(
|
|
888
|
+
result_array.ptr,
|
|
889
|
+
target_device,
|
|
890
|
+
ctypes.byref(device_array),
|
|
891
|
+
)
|
|
892
|
+
check_status(status)
|
|
893
|
+
|
|
894
|
+
if result_array.destroy:
|
|
895
|
+
result_array.destroy(result_array.ptr)
|
|
896
|
+
|
|
897
|
+
result_array = device_array
|
|
898
|
+
|
|
899
|
+
return result_array
|
|
900
|
+
finally:
|
|
901
|
+
if cpu_array.destroy:
|
|
902
|
+
cpu_array.destroy(cpu_array.ptr)
|
|
903
|
+
|
|
904
|
+
|
|
836
905
|
def _normalize_selection(
|
|
837
906
|
selection: Union[Labels, LabelsEntry, Dict[str, int]],
|
|
907
|
+
like: Labels,
|
|
838
908
|
) -> Labels:
|
|
839
909
|
if isinstance(selection, dict):
|
|
840
910
|
for key, value in selection.items():
|
|
@@ -848,11 +918,11 @@ def _normalize_selection(
|
|
|
848
918
|
)
|
|
849
919
|
|
|
850
920
|
if len(selection) == 0:
|
|
851
|
-
return Labels([],
|
|
921
|
+
return Labels([], _array_like([], like))
|
|
852
922
|
else:
|
|
853
923
|
return Labels(
|
|
854
924
|
list(selection.keys()),
|
|
855
|
-
|
|
925
|
+
_array_like([np.int32(v) for v in selection.values()], like),
|
|
856
926
|
)
|
|
857
927
|
|
|
858
928
|
elif isinstance(selection, Labels):
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metatensor-core
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python bindings for metatensor
|
|
5
5
|
Author: Guillaume Fraux, Rohit Goswami, Philip Loche, Filippo Bigi, Joseph W. Abbott, Davide Tisi, Alexander Goscinski, Michele Ceriotti
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
Binary file
|
|
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
|
{metatensor_core-0.2.2 → metatensor_core-0.2.3}/metatensor_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|