| 374 | } |
| 375 | |
| 376 | Status SparseCSFTensorToNdarray(const std::shared_ptr<SparseCSFTensor>& sparse_tensor, |
| 377 | PyObject* base, PyObject** out_data, |
| 378 | PyObject** out_indptr, PyObject** out_indices) { |
| 379 | const auto& sparse_index = arrow::internal::checked_cast<const SparseCSFIndex&>( |
| 380 | *sparse_tensor->sparse_index()); |
| 381 | |
| 382 | // Wrap tensor data |
| 383 | OwnedRef result_data; |
| 384 | RETURN_NOT_OK(SparseTensorDataToNdarray( |
| 385 | *sparse_tensor, {static_cast<npy_intp>(sparse_tensor->non_zero_length()), 1}, base, |
| 386 | result_data.ref())); |
| 387 | |
| 388 | // Wrap indices |
| 389 | int ndim = static_cast<int>(sparse_index.indices().size()); |
| 390 | OwnedRef indptr(PyList_New(ndim - 1)); |
| 391 | OwnedRef indices(PyList_New(ndim)); |
| 392 | RETURN_IF_PYERROR(); |
| 393 | |
| 394 | for (int i = 0; i < ndim - 1; ++i) { |
| 395 | PyObject* item; |
| 396 | RETURN_NOT_OK(TensorToNdarray(sparse_index.indptr()[i], base, &item)); |
| 397 | if (PyList_SetItem(indptr.obj(), i, item) < 0) { |
| 398 | Py_XDECREF(item); |
| 399 | RETURN_IF_PYERROR(); |
| 400 | } |
| 401 | } |
| 402 | for (int i = 0; i < ndim; ++i) { |
| 403 | PyObject* item; |
| 404 | RETURN_NOT_OK(TensorToNdarray(sparse_index.indices()[i], base, &item)); |
| 405 | if (PyList_SetItem(indices.obj(), i, item) < 0) { |
| 406 | Py_XDECREF(item); |
| 407 | RETURN_IF_PYERROR(); |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | *out_indptr = indptr.detach(); |
| 412 | *out_indices = indices.detach(); |
| 413 | *out_data = result_data.detach(); |
| 414 | return Status::OK(); |
| 415 | } |
| 416 | |
| 417 | Status NdarraysToSparseCOOTensor(MemoryPool* pool, PyObject* data_ao, PyObject* coords_ao, |
| 418 | const std::vector<int64_t>& shape, |
nothing calls this directly
no test coverage detected