Support pickling array for bfloat16 (#2586)

* add bfloat16 pickling

* Improvements

* improve

---------

Co-authored-by: Chen-Chen Yeh <ge96noj@mytum.de>
This commit is contained in:
Daniel Yeh
2025-09-23 05:12:15 +02:00
committed by GitHub
parent bf01ad9367
commit fbbf3b9b3e
4 changed files with 36 additions and 12 deletions
+29 -4
View File
@@ -466,12 +466,37 @@ void init_array(nb::module_& m) {
})
.def(
"__iter__", [](const mx::array& a) { return ArrayPythonIterator(a); })
.def("__getstate__", &mlx_to_np_array)
.def(
"__getstate__",
[](const mx::array& a) {
auto nd = (a.dtype() == mx::bfloat16)
? mlx_to_np_array(mx::view(a, mx::uint16))
: mlx_to_np_array(a);
return nb::make_tuple(nd, static_cast<uint8_t>(a.dtype().val()));
})
.def(
"__setstate__",
[](mx::array& arr,
const nb::ndarray<nb::ro, nb::c_contig, nb::device::cpu>& state) {
new (&arr) mx::array(nd_array_to_mlx(state, std::nullopt));
[](mx::array& arr, const nb::tuple& state) {
if (nb::len(state) != 2) {
throw std::invalid_argument(
"Invalid pickle state: expected (ndarray, Dtype::Val)");
}
using ND = nb::ndarray<nb::ro, nb::c_contig, nb::device::cpu>;
ND nd = nb::cast<ND>(state[0]);
auto val = static_cast<mx::Dtype::Val>(nb::cast<uint8_t>(state[1]));
if (val == mx::Dtype::Val::bfloat16) {
auto owner = nb::handle(state[0].ptr());
new (&arr) mx::array(nd_array_to_mlx(
ND(nd.data(),
nd.ndim(),
reinterpret_cast<const size_t*>(nd.shape_ptr()),
owner,
nullptr,
nb::bfloat16),
mx::bfloat16));
} else {
new (&arr) mx::array(nd_array_to_mlx(nd, std::nullopt));
}
})
.def("__dlpack__", [](const mx::array& a) { return mlx_to_dlpack(a); })
.def(