Copilot commented on code in PR #50929:
URL: https://github.com/apache/arrow/pull/50929#discussion_r3822524334
##########
cpp/src/arrow/c/dlpack.cc:
##########
@@ -215,18 +208,10 @@ Result<DT*> ExportTensorImpl(const
std::shared_ptr<Tensor>& t, bool copy) {
const auto& type = *t->type();
ARROW_ASSIGN_OR_RAISE(auto dtype, GetDLDataType(type));
- // Compute strides
- std::vector<int64_t> strides = {};
- strides.reserve(t->ndim());
- const auto byte_width = type.byte_width();
- for (auto i : t->strides()) {
- strides.emplace_back(i / byte_width);
- }
-
auto params = ExportBufferParams<std::vector<int64_t>>{
- .size = t->size(),
+ .buffer_size = t->size(),
Review Comment:
ExportTensorImpl sets ExportBufferParams::buffer_size to t->size() (element
count), but the struct documents/uses buffer_size as a byte count (e.g.
ExportArrayImpl uses it as CopySlice nbytes). This inconsistency can lead to
incorrect behavior if buffer_size is later used beyond the empty-check.
##########
cpp/src/arrow/c/dlpack_test.cc:
##########
@@ -182,7 +191,11 @@ TYPED_TEST(TestExportArray, TestErrors) {
const std::shared_ptr<Array> array_boolean = ArrayFromJSON(boolean(),
"[true, false]");
ASSERT_RAISES_WITH_MESSAGE(
TypeError, "Type error: Bit-packed boolean data type not supported by
DLPack.",
- arrow::dlpack::ExportDevice(array_boolean));
+ TypeParam::Export(array_boolean));
Review Comment:
The expected error strings for unsupported types (null/utf8) no longer match
the updated TypeError message from GetDLDataType (which now appends a Tensor
conversion hint), so this test will fail.
##########
cpp/src/arrow/array/array_primitive.h:
##########
@@ -128,6 +130,19 @@ class NumericArray : public PrimitiveArray {
IteratorType end() const { return IteratorType(*this, length()); }
+ /// \brief Return a one dimensional Tensor.
+ Result<std::shared_ptr<Tensor>> ToTensor() const override {
+ // Could be non-templated
+ const int64_t byte_width = type()->byte_width();
+ std::shared_ptr<Buffer> buffer;
+ if (data_->buffers[1] != NULLPTR) {
+ const auto boffset = data_->offset * byte_width;
+ const auto blength = length() * byte_width;
+ ARROW_ASSIGN_OR_RAISE(buffer, SliceBufferSafe(data_->buffers[1],
boffset, blength));
+ }
+ return Tensor::Make(type(), std::move(buffer), {length()});
Review Comment:
If the values buffer is absent (data_->buffers[1] == NULLPTR), buffer
remains null and Tensor::Make will fail with "Null data is supplied" even for a
valid empty NumericArray. Consider providing a 0-length Buffer when no values
buffer exists.
##########
cpp/src/arrow/array/array_nested.cc:
##########
@@ -1001,6 +1001,40 @@ Result<std::shared_ptr<Array>>
FixedSizeListArray::Flatten(
return FlattenListArray(*this, memory_pool);
}
+Result<std::shared_ptr<Tensor>> FixedSizeListArray::ToTensor() const {
+ const auto* data = this->data().get();
+ auto type = this->type();
+ int64_t offset = data->offset;
+ int64_t length = data->length;
+ std::vector<int64_t> shape{length};
+
+ // Iterate over nested fixed length container types.
+ // Each nested container increase the tensor dimension.
+ while (type->id() == Type::FIXED_SIZE_LIST) {
+ const auto* fsl = internal::checked_cast<const
FixedSizeListType*>(type.get());
+ type = fsl->value_type();
+ data = data->child_data.front().get();
+
+ offset = offset * fsl->list_size() + data->offset;
+ length *= fsl->list_size();
+ shape.push_back(fsl->list_size());
+ }
+
+ // Only checking byte_width and leaving Tensor::Make error on unsupported
types.
+ if (!is_fixed_width(*type)) {
+ return Status::NotImplemented("Expected a fixed width leaf type, got ",
type->name());
+ }
+
+ std::shared_ptr<Buffer> buffer = nullptr;
+ if (const auto& buf = data->buffers[1]; buf != NULLPTR) {
+ const int64_t byte_width = type->byte_width();
+ ARROW_ASSIGN_OR_RAISE(buffer,
+ SliceBufferSafe(buf, offset * byte_width, length *
byte_width));
+ }
+
+ return Tensor::Make(std::move(type), std::move(buffer), std::move(shape));
Review Comment:
If the leaf values buffer is absent (data->buffers[1] == NULLPTR), buffer
stays null and Tensor::Make will fail with "Null data is supplied" even for a
valid empty FixedSizeListArray. Consider providing a 0-length Buffer when no
values buffer exists.
##########
python/pyarrow/tests/test_dlpack.py:
##########
@@ -145,6 +145,32 @@ def test_tensor_dlpack(np_type):
check_dlpack_export(t, expected)
+def multidim_arrays():
+ np_arr = np.arange(12, dtype=np.int32).reshape(3, 2, 2)
+ values = pa.array(np_arr.ravel(), type=pa.int32())
+ nested_list = pa.FixedSizeListArray.from_arrays(
+ pa.FixedSizeListArray.from_arrays(values, 2), 2)
+ return [
+ pytest.param(nested_list, np_arr, id="nested_fixed_size_list"),
+ pytest.param(
+ pa.FixedShapeTensorArray.from_numpy_ndarray(np_arr),
+ np_arr,
+ id="fixed_shape_tensor",
+ ),
+ ]
+
+
+@check_bytes_allocated
[email protected](('arr', 'expected'), multidim_arrays())
+def test_array_to_tensor_dlpack(arr, expected):
+ if Version(np.__version__) < Version("1.24.0"):
+ pytest.skip("No dlpack support in numpy versions older than 1.22.0, "
+ "strict keyword in assert_array_equal added in numpy
version "
+ "1.24.0")
Review Comment:
The skip message says "No dlpack support ... older than 1.22.0" but the
condition is numpy < 1.24.0. Update the message to reflect the actual minimum
required version.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]