| 466 | } |
| 467 | |
| 468 | nb::object PyTensor::tolist() const { |
| 469 | validate(); |
| 470 | Tensor cpu_tensor = tensor_.device() == Device::CUDA ? tensor_.cpu() : tensor_; |
| 471 | if (!cpu_tensor.is_contiguous()) { |
| 472 | cpu_tensor = cpu_tensor.contiguous(); |
| 473 | } |
| 474 | |
| 475 | const auto& dims = cpu_tensor.shape().dims(); |
| 476 | size_t offset = 0; |
| 477 | |
| 478 | switch (cpu_tensor.dtype()) { |
| 479 | case DataType::Float32: { |
| 480 | const auto values = cpu_tensor.to_vector(); |
| 481 | return build_nested_list(dims, 0, offset, [&](size_t index) { return nb::cast(values[index]); }); |
| 482 | } |
| 483 | case DataType::Int32: { |
| 484 | const auto values = cpu_tensor.to_vector_int(); |
| 485 | return build_nested_list(dims, 0, offset, [&](size_t index) { return nb::cast(values[index]); }); |
| 486 | } |
| 487 | case DataType::Int64: { |
| 488 | const auto values = cpu_tensor.to_vector_int64(); |
| 489 | return build_nested_list(dims, 0, offset, [&](size_t index) { return nb::cast(values[index]); }); |
| 490 | } |
| 491 | case DataType::UInt8: { |
| 492 | const auto values = cpu_tensor.to_vector_uint8(); |
| 493 | return build_nested_list(dims, 0, offset, [&](size_t index) { return nb::cast(values[index]); }); |
| 494 | } |
| 495 | case DataType::Bool: { |
| 496 | const auto values = cpu_tensor.to_vector_bool(); |
| 497 | return build_nested_list(dims, 0, offset, [&](size_t index) { return nb::cast(static_cast<bool>(values[index])); }); |
| 498 | } |
| 499 | default: |
| 500 | throw std::runtime_error("Unsupported dtype for tolist conversion"); |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | size_t PyTensor::count_nonzero() const { |
| 505 | validate(); |