gemini-code-assist[bot] commented on code in PR #604:
URL: https://github.com/apache/tvm-ffi/pull/604#discussion_r3352491832


##########
python/tvm_ffi/cython/tensor.pxi:
##########
@@ -276,6 +276,52 @@ cdef class Tensor(CObject):
         """Tensor shape as a tuple of integers."""
         return tuple(self.cdltensor.shape[i] for i in 
range(self.cdltensor.ndim))
 
+    @property
+    def ndim(self) -> int:
+        """Number of dimensions of the tensor."""
+        return self.cdltensor.ndim
+
+    def numel(self) -> int:
+        """Total number of elements in the tensor."""
+        cdef int64_t count = 1
+        cdef int i
+        for i in range(self.cdltensor.ndim):
+            count *= self.cdltensor.shape[i]
+        return count
+
+    def size(self, idx: int) -> int:
+        """Get the size of the ``idx``-th dimension. Negative ``idx`` counts 
from the last dimension.
+        """
+        cdef int ndim = self.cdltensor.ndim
+        if idx < -ndim or idx >= ndim:
+            raise IndexError(
+                f"Dimension {idx} out of range for tensor with {ndim} 
dimensions"
+            )
+        if idx < 0:
+            idx += ndim
+        return self.cdltensor.shape[idx]
+
+    def is_contiguous(self) -> bool:
+        """True if the Tensor is C-contiguous (row-major), False otherwise."""
+        if self.cdltensor.strides == NULL:
+            return True

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   For empty tensors (where any dimension is 0, e.g., shape `(3, 0, 4)`), the 
current implementation of `is_contiguous` will incorrectly return `False`. This 
is because after encountering the 0-sized dimension, `expected_stride` becomes 
`0`, causing subsequent stride checks for non-zero dimensions to fail (e.g., 
`strides[0] != 0`). Empty tensors are always considered contiguous by standard 
convention (e.g., in NumPy and PyTorch). Adding an early return when 
`self.numel() == 0` resolves this issue.
   
   ```
       def is_contiguous(self) -> bool:
           """True if the Tensor is C-contiguous (row-major), False 
otherwise."""
           if self.numel() == 0:
               return True
           if self.cdltensor.strides == NULL:
               return True
   ```



##########
tests/python/test_tensor.py:
##########
@@ -39,6 +39,12 @@ def test_tensor_attributes() -> None:
     x = tvm_ffi.from_dlpack(data)
     assert isinstance(x, tvm_ffi.Tensor)
     assert x.shape == (10, 8, 4, 2)
+    assert x.ndim == 4
+    assert x.numel() == 640
+    assert x.size(0) == 10
+    assert x.size(-1) == 2
+    assert x.is_contiguous()

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   It is highly recommended to also test `is_contiguous()` on non-contiguous 
tensors (e.g., transposed arrays) and empty tensors with 0-sized dimensions 
(e.g., shape `(3, 0, 4)`) to ensure correctness across all layouts.
   
   ```suggestion
       assert x.is_contiguous()
       non_contig_data = data.T
       if hasattr(non_contig_data, "__dlpack__"):
           y = tvm_ffi.from_dlpack(non_contig_data)
           assert not y.is_contiguous()
       empty_data = np.zeros((3, 0, 4), dtype="int16")
       if hasattr(empty_data, "__dlpack__"):
           z = tvm_ffi.from_dlpack(empty_data)
           assert z.is_contiguous()
   ```



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to