jorisvandenbossche commented on code in PR #37533:
URL: https://github.com/apache/arrow/pull/37533#discussion_r1423652324
##########
cpp/src/arrow/extension/fixed_shape_tensor.cc:
##########
@@ -298,25 +344,25 @@ const Result<std::shared_ptr<Tensor>>
FixedShapeTensorArray::ToTensor() const {
ARROW_RETURN_IF(!is_fixed_width(*ext_arr->value_type()),
Status::Invalid(ext_arr->value_type()->ToString(),
" is not valid data type for a tensor"));
- auto permutation = ext_type->permutation();
- std::vector<std::string> dim_names;
- if (!ext_type->dim_names().empty()) {
- for (auto i : permutation) {
- dim_names.emplace_back(ext_type->dim_names()[i]);
+ std::vector<int64_t> permutation = ext_type->permutation();
+ if (permutation.empty()) {
+ for (int64_t i = 0; i < static_cast<int64_t>(ext_type->ndim()); i++) {
+ permutation.emplace_back(i);
}
- dim_names.insert(dim_names.begin(), 1, "");
- } else {
- dim_names = {};
}
+ for (int64_t i = 0; i < static_cast<int64_t>(ext_type->ndim()); i++) {
+ permutation[i] += 1;
+ }
+ permutation.insert(permutation.begin(), 1, 0);
- std::vector<int64_t> shape;
- for (int64_t& i : permutation) {
- shape.emplace_back(ext_type->shape()[i]);
- ++i;
Review Comment:
Why is this permutating of the shape no longer needed?
##########
cpp/src/arrow/extension/fixed_shape_tensor.h:
##########
@@ -43,6 +43,14 @@ class ARROW_EXPORT FixedShapeTensorArray : public
ExtensionArray {
/// dimensions as the FixedShapeTensorType's shape. Shape and dim_names will
be
/// permuted according to permutation stored in the FixedShapeTensorType
metadata.
const Result<std::shared_ptr<Tensor>> ToTensor() const;
+
+ /// \brief Get i-th Tensor from FixedShapeTensorArray
+ ///
+ /// This method will return a Tensor from FixedShapeTensorArray with strides
+ /// derived from shape and permutation of FixedShapeTensorArray. Shape and
+ /// dim_names will be permuted according to permutation stored in the
+ /// FixedShapeTensorArray metadata.
+ const Result<std::shared_ptr<Tensor>> GetTensor(const int64_t i) const;
Review Comment:
Is it needed to have this GetTensor method both on the array and the type
classes? (and same for the Python API)
##########
cpp/src/arrow/extension/fixed_shape_tensor.h:
##########
@@ -94,6 +102,10 @@ class ARROW_EXPORT FixedShapeTensorType : public
ExtensionType {
/// Create a FixedShapeTensorArray from ArrayData
std::shared_ptr<Array> MakeArray(std::shared_ptr<ArrayData> data) const
override;
+ /// \brief Create a FixedShapeTensorArray from a Scalar Tensor
+ const Result<std::shared_ptr<Tensor>> GetTensor(
Review Comment:
Wrong docstring?
##########
cpp/src/arrow/extension/fixed_shape_tensor_test.cc:
##########
@@ -321,6 +324,70 @@ TEST_F(TestExtensionType, TestFromTensorType) {
}
}
+void CheckToTensor(const std::vector<int64_t> values, const int64_t cell_size,
+ const std::vector<int64_t> cell_shape,
+ const std::vector<int64_t> cell_permutation,
+ const std::vector<std::string> cell_dim_names,
+ const std::vector<int64_t> tensor_shape,
+ const std::vector<std::string> tensor_dim_names,
+ const std::vector<int64_t> tensor_strides) {
+ auto buffer = Buffer::Wrap(values);
+ const std::shared_ptr<DataType> cell_type = fixed_size_list(int64(),
cell_size);
+ std::vector<std::shared_ptr<Buffer>> buffers = {nullptr, buffer};
+ auto arr_data = std::make_shared<ArrayData>(int64(), values.size(), buffers);
+ auto arr = std::make_shared<Int64Array>(arr_data);
+ ASSERT_OK_AND_ASSIGN(auto fsla_arr, FixedSizeListArray::FromArrays(arr,
cell_type));
+
+ ASSERT_OK_AND_ASSIGN(
+ auto expected_tensor,
+ Tensor::Make(int64(), buffer, tensor_shape, tensor_strides,
tensor_dim_names));
+ const auto ext_type =
+ fixed_shape_tensor(int64(), cell_shape, cell_permutation,
cell_dim_names);
+
+ auto ext_arr = ExtensionType::WrapArray(ext_type, fsla_arr);
+ const auto tensor_array =
std::static_pointer_cast<FixedShapeTensorArray>(ext_arr);
+ ASSERT_OK_AND_ASSIGN(const auto actual_tensor, tensor_array->ToTensor());
+
+ ASSERT_EQ(actual_tensor->type(), expected_tensor->type());
+ ASSERT_EQ(actual_tensor->shape(), expected_tensor->shape());
+ ASSERT_EQ(actual_tensor->strides(), expected_tensor->strides());
+ ASSERT_EQ(actual_tensor->dim_names(), expected_tensor->dim_names());
+ ASSERT_TRUE(actual_tensor->data()->Equals(*expected_tensor->data()));
+ ASSERT_TRUE(actual_tensor->Equals(*expected_tensor));
+}
+
+TEST_F(TestExtensionType, ToTensor) {
+ auto cell_sizes = std::vector<int64_t>{12, 12, 12, 12, 6, 6, 18, 18, 18, 18};
+
+ auto cell_shapes =
+ std::vector<std::vector<int64_t>>{{3, 4}, {4, 3}, {4, 3}, {3, 4}, {2,
3},
+ {3, 2}, {3, 6}, {6, 3}, {3, 2, 3}, {3,
2, 3}};
+ auto tensor_shapes = std::vector<std::vector<int64_t>>{
+ {3, 3, 4}, {3, 4, 3}, {3, 4, 3}, {3, 3, 4}, {6, 2, 3},
+ {6, 3, 2}, {2, 3, 6}, {2, 6, 3}, {2, 3, 2, 3}, {2, 3, 2, 3}};
+
+ auto cell_permutations =
+ std::vector<std::vector<int64_t>>{{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0,
1},
+ {1, 0}, {0, 1}, {1, 0}, {0, 1, 2}, {2,
1, 0}};
+ auto tensor_strides = std::vector<std::vector<int64_t>>{
+ {96, 32, 8}, {96, 8, 32}, {96, 24, 8}, {96, 8, 24}, {48, 24, 8},
+ {48, 8, 24}, {144, 48, 8}, {144, 8, 48}, {144, 48, 24, 8}, {144, 8, 24,
48}};
+
+ auto cell_dim_names = std::vector<std::vector<std::string>>{
+ {"y", "z"}, {"y", "z"}, {"y", "z"}, {"y", "z"}, {"y", "z"},
+ {"y", "z"}, {"y", "z"}, {"y", "z"}, {"H", "W", "C"}, {"H", "W", "C"}};
+ auto tensor_dim_names = std::vector<std::vector<std::string>>{
+ {"", "y", "z"}, {"", "y", "z"}, {"", "y", "z"}, {"", "y", "z"},
+ {"", "y", "z"}, {"", "y", "z"}, {"", "y", "z"}, {"", "y", "z"},
+ {"", "H", "W", "C"}, {"", "H", "W", "C"}};
Review Comment:
The cell dim names for the FixedShapeTensor should match the non-permuted
physical layout (according to the spec), while I assume for the Tensor class
this matches the logical (strided) layout? (the doc is not super clear about
this)
If that's the case, I would expect permuted expected values above?
##########
python/pyarrow/array.pxi:
##########
@@ -3518,17 +3518,38 @@ class FixedShapeTensorArray(ExtensionArray):
def to_numpy_ndarray(self):
"""
- Convert fixed shape tensor extension array to a numpy array (with
dim+1).
+ Convert fixed shape tensor extension array to a numpy.ndarray with
zero copy.
+ First dimension of ndarray will be the length of the fixed shape
tensor array
+ and the rest of the dimensions will match the shape of the fixed shape
tensor.
Review Comment:
Will it exactly match the shape of the FixedShapeTensor? Not if it gets
permuted?
##########
python/pyarrow/array.pxi:
##########
@@ -3518,17 +3518,38 @@ class FixedShapeTensorArray(ExtensionArray):
def to_numpy_ndarray(self):
"""
- Convert fixed shape tensor extension array to a numpy array (with
dim+1).
+ Convert fixed shape tensor extension array to a numpy.ndarray with
zero copy.
+ First dimension of ndarray will be the length of the fixed shape
tensor array
+ and the rest of the dimensions will match the shape of the fixed shape
tensor.
+ """
+ return self.to_tensor().to_numpy()
+
+ def to_tensor(self):
Review Comment:
Can you add a docstring here?
##########
cpp/src/arrow/extension/fixed_shape_tensor_test.cc:
##########
@@ -344,6 +411,9 @@ TEST_F(TestExtensionType, RoundtripTensor) {
auto strides = std::vector<std::vector<int64_t>>{
{96, 32, 8}, {96, 8, 32}, {96, 24, 8}, {96, 8, 24}, {48, 24, 8},
{48, 8, 24}, {144, 48, 8}, {144, 8, 48}, {144, 48, 24, 8}, {144, 8, 24,
48}};
+ auto permutations =
+ std::vector<std::vector<int64_t>>{{0, 1}, {1, 0}, {0, 1}, {1, 0}, {0,
1},
+ {1, 0}, {0, 1}, {0, 1}, {0, 1, 2}, {2,
1, 0}};
Review Comment:
This new variable isn't used?
##########
python/pyarrow/includes/libarrow.pxd:
##########
@@ -2650,24 +2650,25 @@ cdef extern from "arrow/extension_type.h" namespace
"arrow":
cdef extern from "arrow/extension/fixed_shape_tensor.h" namespace
"arrow::extension":
cdef cppclass CFixedShapeTensorType \
- " arrow::extension::FixedShapeTensorType"(CExtensionType):
+ " arrow::extension::FixedShapeTensorType"(CExtensionType) nogil:
Review Comment:
I think you can add the nogil to the `cdef extern .. namespace ..` line just
above (then you don't need to add it to both classes individually)
##########
python/pyarrow/scalar.pxi:
##########
@@ -1027,6 +1027,32 @@ cdef class ExtensionScalar(Scalar):
return pyarrow_wrap_scalar(<shared_ptr[CScalar]> sp_scalar)
+cdef class FixedShapeTensorScalar(ExtensionScalar):
+ """
+ Concrete class for fixed shape tensor extension scalar.
+ """
+
+ def to_numpy_ndarray(self):
+ """
+ Convert fixed shape tensor extension scalar to a numpy.ndarray with
zero copy.
+ """
+ return self.to_tensor().to_numpy()
+
+ def to_tensor(self):
+ """
+ Convert fixed shape tensor extension scalar to a pyarrow.Tensor.
Review Comment:
Can you add a Returns section? (then that will link to the pyarrow.Tensor
docs I think)
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
Review Comment:
The tensor is using float32?
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
tensor_type = pa.fixed_shape_tensor(pa.float32(), [2, 3])
- storage = pa.array([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]],
- pa.list_(pa.float32(), 6))
+ storage = pa.array(np_arr.reshape(2, 6).tolist(), pa.list_(pa.float32(),
6))
arr = pa.ExtensionArray.from_storage(tensor_type, storage)
- expected = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
- result = arr.to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
- expected = np.array([[[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
+ # TODO: add more get_tensor tests
+ assert arr.get_tensor(0) == pa.Tensor.from_numpy(
+ np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
+
+ expected = np_arr.reshape(2, 2, 3).astype(np.float32).tolist()
+ np.testing.assert_array_equal(arr.to_tensor(), expected)
+ np.testing.assert_array_equal(arr.to_numpy_ndarray(), expected)
+
+ # TODO: offset not correctly handled
+ expected = np_arr[6:].reshape(1, 2, 3).astype(np.float32)
+ # expected = np.array([[[7, 8, 9], [10, 11, 12]]], dtype=np.float32)
result = arr[:1].to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
+ # np.testing.assert_array_equal(result, expected)
Review Comment:
uncomment?
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
tensor_type = pa.fixed_shape_tensor(pa.float32(), [2, 3])
- storage = pa.array([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]],
- pa.list_(pa.float32(), 6))
+ storage = pa.array(np_arr.reshape(2, 6).tolist(), pa.list_(pa.float32(),
6))
Review Comment:
I personally find the previous way easier to read. I think it's fine to
repeat the values for readability.
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
tensor_type = pa.fixed_shape_tensor(pa.float32(), [2, 3])
- storage = pa.array([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]],
- pa.list_(pa.float32(), 6))
+ storage = pa.array(np_arr.reshape(2, 6).tolist(), pa.list_(pa.float32(),
6))
arr = pa.ExtensionArray.from_storage(tensor_type, storage)
- expected = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
- result = arr.to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
- expected = np.array([[[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
+ # TODO: add more get_tensor tests
+ assert arr.get_tensor(0) == pa.Tensor.from_numpy(
+ np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
+
+ expected = np_arr.reshape(2, 2, 3).astype(np.float32).tolist()
+ np.testing.assert_array_equal(arr.to_tensor(), expected)
+ np.testing.assert_array_equal(arr.to_numpy_ndarray(), expected)
+
+ # TODO: offset not correctly handled
+ expected = np_arr[6:].reshape(1, 2, 3).astype(np.float32)
+ # expected = np.array([[[7, 8, 9], [10, 11, 12]]], dtype=np.float32)
result = arr[:1].to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
+ # np.testing.assert_array_equal(result, expected)
arr = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]],
+ [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]],
dtype=np.float32, order="C")
tensor_array_from_numpy = pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
Review Comment:
I know this was already mixed up now, but since you are expanding the tests,
can you split it? For example separate the `from_numpy_ndarray` parts into
their own test?
##########
cpp/src/arrow/extension/fixed_shape_tensor.cc:
##########
@@ -203,6 +215,40 @@ std::shared_ptr<Array> FixedShapeTensorType::MakeArray(
return std::make_shared<ExtensionArray>(data);
}
+const Result<std::shared_ptr<Tensor>> FixedShapeTensorType::GetTensor(
+ const std::shared_ptr<ExtensionScalar>& scalar) const {
+ const auto array =
+ internal::checked_pointer_cast<const
FixedSizeListScalar>(scalar->value)->value;
+ const auto value_type =
+ internal::checked_pointer_cast<FixedWidthType>(this->value_type());
Review Comment:
This should first validate that it is indeed a fixed width type (and if not
raise a proper error message) instead of just casting?
Also, it should probably check that there are no nulls?
(and add tests for this)
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
tensor_type = pa.fixed_shape_tensor(pa.float32(), [2, 3])
- storage = pa.array([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]],
- pa.list_(pa.float32(), 6))
+ storage = pa.array(np_arr.reshape(2, 6).tolist(), pa.list_(pa.float32(),
6))
arr = pa.ExtensionArray.from_storage(tensor_type, storage)
- expected = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
- result = arr.to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
- expected = np.array([[[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
+ # TODO: add more get_tensor tests
+ assert arr.get_tensor(0) == pa.Tensor.from_numpy(
+ np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
+
+ expected = np_arr.reshape(2, 2, 3).astype(np.float32).tolist()
+ np.testing.assert_array_equal(arr.to_tensor(), expected)
+ np.testing.assert_array_equal(arr.to_numpy_ndarray(), expected)
+
+ # TODO: offset not correctly handled
+ expected = np_arr[6:].reshape(1, 2, 3).astype(np.float32)
+ # expected = np.array([[[7, 8, 9], [10, 11, 12]]], dtype=np.float32)
result = arr[:1].to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
+ # np.testing.assert_array_equal(result, expected)
arr = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]],
+ [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]],
dtype=np.float32, order="C")
tensor_array_from_numpy = pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
assert isinstance(tensor_array_from_numpy.type, pa.FixedShapeTensorType)
assert tensor_array_from_numpy.type.value_type == pa.float32()
assert tensor_array_from_numpy.type.shape == [2, 3]
- arr = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]],
- dtype=np.float32, order="F")
- with pytest.raises(ValueError, match="C-style contiguous segment"):
+ arr = np_arr.reshape((-1, 3), order="F")
+ with pytest.raises(ValueError, match="First stride needs to be largest"):
pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
+ bw = np.int8().itemsize
+ arr = as_strided(np_arr, shape=(3, 4), strides=(bw * 4, bw),
writeable=False)
Review Comment:
```suggestion
arr = np_arr.reshape(3, 4)
```
?
##########
python/pyarrow/tests/test_extension_type.py:
##########
@@ -1319,38 +1319,65 @@ def test_tensor_type():
def test_tensor_class_methods():
+ from numpy.lib.stride_tricks import as_strided
+
+ values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ np_arr = np.array(values, dtype=np.int8)
tensor_type = pa.fixed_shape_tensor(pa.float32(), [2, 3])
- storage = pa.array([[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]],
- pa.list_(pa.float32(), 6))
+ storage = pa.array(np_arr.reshape(2, 6).tolist(), pa.list_(pa.float32(),
6))
arr = pa.ExtensionArray.from_storage(tensor_type, storage)
- expected = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
- result = arr.to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
- expected = np.array([[[1, 2, 3], [4, 5, 6]]], dtype=np.float32)
+ # TODO: add more get_tensor tests
+ assert arr.get_tensor(0) == pa.Tensor.from_numpy(
+ np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
+
+ expected = np_arr.reshape(2, 2, 3).astype(np.float32).tolist()
+ np.testing.assert_array_equal(arr.to_tensor(), expected)
+ np.testing.assert_array_equal(arr.to_numpy_ndarray(), expected)
+
+ # TODO: offset not correctly handled
+ expected = np_arr[6:].reshape(1, 2, 3).astype(np.float32)
+ # expected = np.array([[[7, 8, 9], [10, 11, 12]]], dtype=np.float32)
result = arr[:1].to_numpy_ndarray()
- np.testing.assert_array_equal(result, expected)
+ # np.testing.assert_array_equal(result, expected)
arr = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]],
+ [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]],
dtype=np.float32, order="C")
tensor_array_from_numpy = pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
assert isinstance(tensor_array_from_numpy.type, pa.FixedShapeTensorType)
assert tensor_array_from_numpy.type.value_type == pa.float32()
assert tensor_array_from_numpy.type.shape == [2, 3]
- arr = np.array(
- [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]],
- dtype=np.float32, order="F")
- with pytest.raises(ValueError, match="C-style contiguous segment"):
+ arr = np_arr.reshape((-1, 3), order="F")
+ with pytest.raises(ValueError, match="First stride needs to be largest"):
pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
+ bw = np.int8().itemsize
+ arr = as_strided(np_arr, shape=(3, 4), strides=(bw * 4, bw),
writeable=False)
+ tensor_array_from_numpy = pa.FixedShapeTensorArray.from_numpy_ndarray(arr)
+ assert tensor_array_from_numpy.type.shape == [4]
+ assert tensor_array_from_numpy.type.permutation == [1]
Review Comment:
The spec says: "The indices contain a permutation of the values [0, 1, ..,
N-1] where N is the number of dimensions.", so how can this be [1] ?
##########
cpp/src/arrow/extension/fixed_shape_tensor.cc:
##########
@@ -298,25 +344,25 @@ const Result<std::shared_ptr<Tensor>>
FixedShapeTensorArray::ToTensor() const {
ARROW_RETURN_IF(!is_fixed_width(*ext_arr->value_type()),
Status::Invalid(ext_arr->value_type()->ToString(),
" is not valid data type for a tensor"));
- auto permutation = ext_type->permutation();
- std::vector<std::string> dim_names;
- if (!ext_type->dim_names().empty()) {
- for (auto i : permutation) {
- dim_names.emplace_back(ext_type->dim_names()[i]);
+ std::vector<int64_t> permutation = ext_type->permutation();
+ if (permutation.empty()) {
+ for (int64_t i = 0; i < static_cast<int64_t>(ext_type->ndim()); i++) {
+ permutation.emplace_back(i);
}
- dim_names.insert(dim_names.begin(), 1, "");
- } else {
- dim_names = {};
}
+ for (int64_t i = 0; i < static_cast<int64_t>(ext_type->ndim()); i++) {
+ permutation[i] += 1;
+ }
+ permutation.insert(permutation.begin(), 1, 0);
- std::vector<int64_t> shape;
- for (int64_t& i : permutation) {
- shape.emplace_back(ext_type->shape()[i]);
- ++i;
Review Comment:
(the C++ tests are also failing, potentially related)
--
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]