| 217 | } |
| 218 | |
| 219 | nb::object tolist(mx::array& a) { |
| 220 | if (a.ndim() == 0) { |
| 221 | return to_scalar(a); |
| 222 | } |
| 223 | { |
| 224 | nb::gil_scoped_release nogil; |
| 225 | a.eval(); |
| 226 | } |
| 227 | switch (a.dtype()) { |
| 228 | case mx::bool_: |
| 229 | return to_list<bool>(a, 0, 0); |
| 230 | case mx::uint8: |
| 231 | return to_list<uint8_t>(a, 0, 0); |
| 232 | case mx::uint16: |
| 233 | return to_list<uint16_t>(a, 0, 0); |
| 234 | case mx::uint32: |
| 235 | return to_list<uint32_t>(a, 0, 0); |
| 236 | case mx::uint64: |
| 237 | return to_list<uint64_t>(a, 0, 0); |
| 238 | case mx::int8: |
| 239 | return to_list<int8_t>(a, 0, 0); |
| 240 | case mx::int16: |
| 241 | return to_list<int16_t>(a, 0, 0); |
| 242 | case mx::int32: |
| 243 | return to_list<int32_t>(a, 0, 0); |
| 244 | case mx::int64: |
| 245 | return to_list<int64_t>(a, 0, 0); |
| 246 | case mx::float16: |
| 247 | return to_list<mx::float16_t, float>(a, 0, 0); |
| 248 | case mx::float32: |
| 249 | return to_list<float>(a, 0, 0); |
| 250 | case mx::bfloat16: |
| 251 | return to_list<mx::bfloat16_t, float>(a, 0, 0); |
| 252 | case mx::float64: |
| 253 | return to_list<double>(a, 0, 0); |
| 254 | case mx::complex64: |
| 255 | return to_list<std::complex<float>>(a, 0, 0); |
| 256 | default: |
| 257 | throw nb::type_error("data type cannot be converted to Python list."); |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | template <typename T, typename U> |
| 262 | void fill_vector(T list, std::vector<U>& vals) { |