GH-39295: [C++][Python] ConsumingDLPack on Arrays and Tensor - #51122
GH-39295: [C++][Python] ConsumingDLPack on Arrays and Tensor#51122AntoinePrv wants to merge 6 commits into
Conversation
|
|
94fafe8 to
85740f4
Compare
8d1eca2 to
2fe859d
Compare
There was a problem hiding this comment.
🟡 Changes recommended
There is a likely C++ compile-breaking scoping issue in cpp/src/arrow/tensor.cc around the stride helper functions, plus several doc/API consistency issues to resolve.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds DLPack consumer support to Arrow Arrays/Tensors in C++ and exposes new Python factory APIs (Array.from_dlpack, Tensor.from_dlpack), enabling zero-copy (or requested-copy) imports from DLPack-producing libraries (e.g., NumPy, PyTorch).
Changes:
- Add C++ DLPack consumers:
arrow::dlpack::ImportArrayVersionedandarrow::dlpack::ImportTensorVersioned, plus supporting utilities and tests. - Expose Python APIs for importing via versioned DLPack capsules, and bind
FixedShapeTensorArray::FromTensor. - Add Python test coverage for tensor/array import, copy vs zero-copy behavior, and unsupported cases.
File summaries
| File | Description |
|---|---|
| python/pyarrow/tests/test_dlpack.py | Adds Python tests for Tensor.from_dlpack / Array.from_dlpack, including copy semantics and unsupported multidim array import. |
| python/pyarrow/tensor.pxi | Implements Tensor.from_dlpack and wires it to C++ ImportTensorVersioned. |
| python/pyarrow/includes/libarrow.pxd | Declares DLPack version struct/constant and new C++ import APIs for Cython bindings; adds FixedShapeTensorArray::FromTensor. |
| python/pyarrow/array.pxi | Implements Array.from_dlpack and adds FixedShapeTensorArray.from_tensor binding. |
| cpp/src/arrow/tensor.h | Declares ComputeTensorSize helper for stride/shape-based size computation. |
| cpp/src/arrow/tensor.cc | Defines ComputeTensorSize and adjusts internal stride helper placement/calls. |
| cpp/src/arrow/c/dlpack.h | Exposes compiled DLPack version constant and declares new import APIs. |
| cpp/src/arrow/c/dlpack.cc | Implements DLPack version constant and consumer-side import logic for arrays/tensors. |
| cpp/src/arrow/c/dlpack_test.cc | Adds comprehensive C++ tests for importing (ownership, copy vs share, dtype coverage, errors). |
Review details
Suppressed comments (1)
cpp/src/arrow/c/dlpack.h:132
- The parameter doc for
ImportTensorVersionedsaysrawis an "Arrow array", but the function takes aDLManagedTensorVersioned*(a DLPack tensor).
/// \param[in] raw Arrow array
- Files reviewed: 9/9 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness and robustness issues in the new DLPack consumer path (notably error type mismatch for unsupported array layouts, plus missing input validation that can crash on malformed tensors).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 4
- Review effort level: Lite
c940592 to
625aab0
Compare
There was a problem hiding this comment.
🟡 Changes recommended
There is a confirmed C++ compilation issue in tensor.cc, and the Python copy= contract isn’t enforced by the current from_dlpack implementations.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
cpp/src/arrow/tensor.cc:563
Tensor::is_row_major()/is_column_major()callinternal::IsTensorStridesRowMajor/ColumnMajor, but those helpers are defined inside an anonymous namespace nested underarrow::internal(in this translation unit), soarrow::internal::IsTensorStridesRowMajordoesn't exist. This will fail to compile. Consider computing the expected row/column-major strides directly in these methods (or moving the helpers out of the anonymous namespace).
bool Tensor::is_row_major() const {
return internal::IsTensorStridesRowMajor(type_, shape_, strides_);
}
- Files reviewed: 9/9 changed files
- Comments generated: 3
- Review effort level: Lite
625aab0 to
496604c
Compare
There was a problem hiding this comment.
🟡 Changes recommended
There are compile- and correctness-blocking issues in the C++ tensor stride helper linkage and in the Cython from_dlpack implementations (nogil assignment and unchecked capsule consumption marking).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
cpp/src/arrow/tensor.cc:227
Tensor::is_row_major()/is_column_major()callinternal::IsTensorStridesRowMajor/ColumnMajor, but those functions are currently only defined in an anonymous namespace (notarrow::internal), so this won’t compile. DefineIsTensorStridesRowMajorandIsTensorStridesColumnMajorinnamespace internal(next toIsTensorStridesContiguous) or revert the qualified calls.
} // namespace
} // namespace internal
namespace internal {
- Files reviewed: 9/9 changed files
- Comments generated: 3
- Review effort level: Lite
Rationale for this change
There are already utilities to import tensor data from NumPy.
With DLPack standard, it will work across many tensor providers.
What changes are included in this PR?
FixedShapedTensorArray::FromTensorin PythonImportArrayVersionedFromDLPackandImportTensorVersionedFromDLPackin C++Array.from_dlpackandTensor.from_dlpackSimilar to the export, multidimensional tensor import require an explicit step through
Tensor.Array::FromTensoror evenFixedSizeListArray::FromTensor. IMHO it does not feel as necessary in this direction but open to anyone's take one it.Are these changes tested?
Yes.
Are there any user-facing changes?
Yes, new APIs.