Skip to content

Commit 7ab91f6

Browse files
added tests
1 parent 71986ef commit 7ab91f6

2 files changed

Lines changed: 72 additions & 16 deletions

File tree

python/mlx/__array_api_info.py

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
class ArrayNamespaceInfo:
2-
def __init__(self):
3-
pass
4-
52
def capabilities(self):
63
return {
74
"boolean indexing": False,
85
"data-dependent shapes": False,
9-
"max dimensions": None,
6+
"max dimensions": 10,
107
}
118

129
def default_device(self):
@@ -19,19 +16,11 @@ def default_dtypes(self, *, device=None):
1916

2017
if device is not None and not isinstance(device, mx.Device):
2118
raise TypeError("Expected a mlx Device")
22-
device = device if device is not None else self.default_device()
23-
if device.type == mx.gpu:
24-
return {
25-
"real floating": mx.float32,
26-
"complex floating": mx.complex64,
27-
"integral": mx.int32,
28-
"indexing": mx.uint32,
29-
}
3019
return {
31-
"real floating": mx.float64,
20+
"real floating": mx.float32,
3221
"complex floating": mx.complex64,
33-
"integral": mx.int64,
34-
"indexing": mx.uint64,
22+
"integral": mx.int32,
23+
"indexing": mx.int32,
3524
}
3625

3726
def devices(self):
@@ -45,7 +34,48 @@ def devices(self):
4534
return tuple(devices)
4635

4736
def dtypes(self, *, device=None, kind=None):
48-
pass
37+
import mlx.core as mx
38+
39+
if device is not None and not isinstance(device, mx.Device):
40+
raise TypeError("Expected a mlx Device")
41+
device = device if device is not None else self.default_device()
42+
43+
dtypes = {
44+
"bool": mx.bool_,
45+
"int8": mx.int8,
46+
"int16": mx.int16,
47+
"int32": mx.int32,
48+
"int64": mx.int64,
49+
"uint8": mx.uint8,
50+
"uint16": mx.uint16,
51+
"uint32": mx.uint32,
52+
"uint64": mx.uint64,
53+
"float32": mx.float32,
54+
"complex64": mx.complex64,
55+
}
56+
if device.type == mx.cpu:
57+
dtypes["float64"] = mx.float64
58+
if kind is None:
59+
return dtypes
60+
61+
signed = {"int8", "int16", "int32", "int64"}
62+
unsigned = {"uint8", "uint16", "uint32", "uint64"}
63+
real = {"float32", "float64"}
64+
complex_ = {"complex64"}
65+
kinds = {
66+
"bool": {"bool"},
67+
"signed integer": signed,
68+
"unsigned integer": unsigned,
69+
"integral": signed | unsigned,
70+
"real floating": real,
71+
"complex floating": complex_,
72+
"numeric": signed | unsigned | real | complex_,
73+
}
74+
kind = (kind,) if isinstance(kind, str) else kind
75+
if not isinstance(kind, tuple) or any(k not in kinds for k in kind):
76+
raise ValueError(f"Unsupported dtype kind: {kind!r}")
77+
names = {name for k in kind for name in kinds[k]}
78+
return {name: dtype for name, dtype in dtypes.items() if name in names}
4979

5080

5181
def __array_namespace_info__():

python/tests/test_array.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ class TestArrayNamespsceInfo(mlx_tests.MLXTestCase):
5353
def test(self):
5454
namespace = mx.__array_namespace_info__()
5555

56+
self.assertEqual(namespace.default_device(), mx.default_device())
57+
self.assertEqual(
58+
namespace.default_dtypes(),
59+
{
60+
"real floating": mx.float32,
61+
"complex floating": mx.complex64,
62+
"integral": mx.int32,
63+
"indexing": mx.int32,
64+
},
65+
)
66+
self.assertEqual(
67+
namespace.dtypes(device=mx.Device(mx.cpu), kind="real floating"),
68+
{"float32": mx.float32, "float64": mx.float64},
69+
)
70+
if mx.is_available(mx.gpu):
71+
self.assertEqual(
72+
namespace.dtypes(device=mx.Device(mx.gpu), kind="real floating"),
73+
{"float32": mx.float32},
74+
)
75+
self.assertEqual(
76+
namespace.dtypes(kind=("bool", "complex floating")),
77+
{"bool": mx.bool_, "complex64": mx.complex64},
78+
)
79+
with self.assertRaises(ValueError):
80+
namespace.dtypes(kind="invalid")
81+
5682

5783
class TestDtypes(mlx_tests.MLXTestCase):
5884
def test_dtypes(self):

0 commit comments

Comments
 (0)