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


##########
src/relax/op/memory/view.cc:
##########
@@ -167,16 +167,15 @@ Type InferTypeView(const Call& call, const BlockBuilder& 
ctx) {
     output_ndim = data_ty->ndim;
   }
 
-  DataType output_dtype = view_dtype.value_or(data_ty->dtype);
+  DLDataType output_raw_dtype = view_dtype.value_or(data_ty->dtype->dtype);
+  PrimType output_dtype(output_raw_dtype);
 
-  // Helper function, returns the number of bytes per vectorized
-  // element.  Cannot use `DataType::bytes`, as it returns the
-  // number of bytes per scalar element.
-  auto get_size_bytes = [](const DataType& dtype) -> ffi::Optional<IntImm> {
-    if (dtype.is_void()) {
+  // Helper function returns the number of bytes per vectorized element.
+  auto get_size_bytes = [](DLDataType dtype) -> ffi::Optional<IntImm> {
+    if ((((dtype).code == kDLOpaqueHandle) && ((dtype).bits == 0) && 
((dtype).lanes == 0))) {
       return std::nullopt;
     } else {
-      auto size_bits = dtype.bits() * dtype.lanes();
+      auto size_bits = ((dtype).bits) * static_cast<int16_t>((dtype).lanes);
       return IntImm::Int64((size_bits + 7) / 8);
     }
   };

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   We should use the `PrimType` wrapper to safely retrieve the lanes and bits, 
and handle scalable vectors by returning `std::nullopt` since their size cannot 
be determined at compile time.
   
   ```c
     auto get_size_bytes = [](DLDataType dtype) -> ffi::Optional<IntImm> {\n    
PrimType prim_type(dtype);\n    if (prim_type.IsVoid() || 
prim_type.IsScalableVector()) {\n      return std::nullopt;\n    } else {\n     
 auto size_bits = prim_type.bits() * prim_type.lanes();\n      return 
IntImm::Int64((size_bits + 7) / 8);\n    }\n  };
   ```



##########
src/relax/transform/lower_alloc_tensor.cc:
##########
@@ -72,7 +72,8 @@ class Mutator : public ExprMutator {
       }();
 
       PrimExpr nbytes = [&]() -> PrimExpr {
-        PrimExpr nbytes = IntImm::Int64(dtype->value.bytes());
+        PrimExpr nbytes = IntImm::Int64(
+            ((((dtype->value).bits * 
static_cast<int16_t>((dtype->value).lanes)) + 7) / 8));
         for (const auto& dim : shape) {
           nbytes *= dim;
         }

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   When calculating `nbytes` for the tensor allocation, using raw 
`static_cast<int16_t>((dtype->value).lanes)` directly bypasses the safety 
checks in `PrimType`. If the tensor has a scalable vector dtype, this will 
silently produce a negative or overflowed size at compile time.\n\nWe should 
use the `PrimType` wrapper to safely retrieve the lanes and bits, and 
explicitly check that it is not a scalable vector.
   
   ```c
         PrimExpr nbytes = [&]() -> PrimExpr {\n        PrimType 
prim_type(dtype->value);\n        
TVM_FFI_ICHECK(!prim_type.IsScalableVector())\n            << "Cannot allocate 
tensor with scalable vector dtype at compile time.";\n        PrimExpr nbytes = 
IntImm::Int64((prim_type.bits() * prim_type.lanes() + 7) / 8);\n        for 
(const auto& dim : shape) {\n          nbytes *= dim;\n        }
   ```



##########
src/relax/transform/utils.h:
##########
@@ -319,39 +319,39 @@ class FunctionCopier : public SymbolicVarRenewMutator {
  * \return A Constant.
  */
 template <typename T>
-inline Constant MakeConstantScalar(T value, DataType dtype) {
+inline Constant MakeConstantScalar(T value, DLDataType dtype) {
   runtime::Tensor arr = runtime::Tensor::Empty({}, dtype, {kDLCPU, 0});
-  if (dtype == DataType::Float(32)) {
+  if (dtype == DLDataType{kDLFloat, 32, 1}) {
     *static_cast<float*>(arr->data) = static_cast<float>(value);
-  } else if (dtype == DataType::Float(64)) {
+  } else if (dtype == DLDataType{kDLFloat, 64, 1}) {
     *static_cast<double*>(arr->data) = static_cast<double>(value);
-  } else if (dtype == DataType::Int(32)) {
+  } else if (dtype == DLDataType{kDLInt, 32, 1}) {
     *static_cast<int32_t*>(arr->data) = static_cast<int32_t>(value);
-  } else if (dtype == DataType::Int(64)) {
+  } else if (dtype == DLDataType{kDLInt, 64, 1}) {
     *static_cast<int64_t*>(arr->data) = static_cast<int64_t>(value);
-  } else if (dtype == DataType::Bool()) {
+  } else if (dtype == DLDataType{kDLBool, 1, 1}) {

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   In TVM, `kDLBool` is standardly represented with 8 bits (not 1 bit). 
Comparing `dtype` against `DLDataType{kDLBool, 1, 1}` will fail to match 
standard boolean constants, causing them to fall through or fail.\n\nWe should 
change the bit width check to `8` to match the standard boolean representation.
   
   ```c
     } else if (dtype == DLDataType{kDLBool, 8, 1}) {
   ```



##########
src/s_tir/analysis/verify_gpu_code.cc:
##########
@@ -202,38 +204,50 @@ class GPUCodeVerifier : public StmtExprVisitor {
   void CheckBufferIndicesVectorizable(const ffi::Array<PrimExpr> indices) {
     for (const auto index : indices) {
       if (const auto* ramp = index.as<RampNode>()) {
-        if (!is_one(ramp->stride) &&
-            static_cast<size_t>(ramp->dtype.lanes() * ramp->dtype.bytes()) > 
max_vector_bytes_) {
+        PrimType ramp_ty = ramp->ty();
+        DLDataType ramp_dtype = ramp_ty->dtype;
+        if (!is_one(ramp->stride) && ramp_ty.IsFixedLengthVector() &&
+            static_cast<size_t>(static_cast<int16_t>((ramp_dtype).lanes) *
+                                (((ramp_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {
           std::stringstream s;
-          s << "Number of lanes (" << ramp->dtype.lanes() << ") times number 
of bytes ("
-            << ramp->dtype.bytes() << ") for dtype " << ramp->dtype
-            << " is greater than the maximum number of vector bytes (" << 
max_vector_bytes_ << ")";
+          s << "Number of lanes (" << static_cast<int16_t>((ramp_dtype).lanes)
+            << ") times number of bytes (" << (((ramp_dtype).bits + 7) / 8) << 
") for dtype "
+            << ramp_dtype << " is greater than the maximum number of vector 
bytes ("
+            << max_vector_bytes_ << ")";
           errors_.push_back(s.str());
         }
       }
     }
   }
 
   void VisitExpr_(const CastNode* op) {
-    if (op->dtype.is_vector()) {
-      if (static_cast<size_t>(op->dtype.lanes() * op->dtype.bytes()) > 
max_vector_bytes_) {
+    PrimType op_ty = op->ty();
+    DLDataType op_dtype = op_ty->dtype;
+    if (op_ty.IsFixedLengthVector()) {
+      if (static_cast<size_t>(static_cast<int16_t>((op_dtype).lanes) *
+                              (((op_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   We can simplify this by using `op_ty.lanes()` and `op_ty.bits()` directly 
instead of unpacking to `DLDataType` and performing manual bit/lane arithmetic.
   
   ```c
       PrimType op_ty = op->ty();\n    if (op_ty.IsFixedLengthVector()) {\n     
 if (static_cast<size_t>(op_ty.lanes() * ((op_ty.bits() + 7) / 8)) > 
max_vector_bytes_) {
   ```



##########
src/s_tir/analysis/verify_gpu_code.cc:
##########
@@ -76,20 +76,22 @@ class GPUCodeVerifier : public StmtExprVisitor {
         break;
       }
     }
+    DLDataType dtype = op->buffer->dtype->dtype;
     if (storage_scope.rank == runtime::StorageRank::kLocal) {
-      local_memory_per_block_ +=
-          static_cast<size_t>(const_size) * op->buffer->dtype.bytes() * 
op->buffer->dtype.lanes();
+      local_memory_per_block_ += static_cast<size_t>(const_size) * 
(((dtype).bits + 7) / 8) *
+                                 static_cast<int16_t>((dtype).lanes);
     } else if (storage_scope.rank == runtime::StorageRank::kShared) {
-      shared_memory_per_block_ +=
-          static_cast<size_t>(const_size) * op->buffer->dtype.bytes() * 
op->buffer->dtype.lanes();
+      shared_memory_per_block_ += static_cast<size_t>(const_size) * 
(((dtype).bits + 7) / 8) *
+                                  static_cast<int16_t>((dtype).lanes);
     }
-    if (op->buffer->dtype.is_vector()) {
-      if (static_cast<size_t>(op->buffer->dtype.lanes() * 
op->buffer->dtype.bytes()) >
+    if ((static_cast<int16_t>((dtype).lanes) > 1)) {
+      if (static_cast<size_t>(static_cast<int16_t>((dtype).lanes) * 
(((dtype).bits + 7) / 8)) >

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Since `op->buffer->dtype` is already a `PrimType`, we can use its member 
functions `bits()` and `lanes()` directly instead of unpacking it to 
`DLDataType` and performing manual bit/lane arithmetic. This is safer and more 
readable.
   
   ```c
       PrimType dtype = op->buffer->dtype;\n    if (storage_scope.rank == 
runtime::StorageRank::kLocal) {\n      local_memory_per_block_ += 
static_cast<size_t>(const_size) * ((dtype.bits() + 7) / 8) *\n                  
               dtype.lanes();\n    } else if (storage_scope.rank == 
runtime::StorageRank::kShared) {\n      shared_memory_per_block_ += 
static_cast<size_t>(const_size) * ((dtype.bits() + 7) / 8) *\n                  
                dtype.lanes();\n    }\n    if (dtype.IsFixedLengthVector()) {\n 
     if (static_cast<size_t>(dtype.lanes() * ((dtype.bits() + 7) / 8)) >
   ```



##########
src/relax/transform/static_plan_block_memory.cc:
##########
@@ -135,10 +135,10 @@ class StorageTokenNode : public ffi::Object {
  */
 class StorageToken : public ffi::ObjectRef {
  public:
-  explicit StorageToken(ffi::Array<PrimExpr> shape, DataType dtype, 
std::string storage_scope,
+  explicit StorageToken(ffi::Array<PrimExpr> shape, DLDataType dtype, 
std::string storage_scope,
                         ffi::Optional<VDevice> vdevice = std::nullopt) {
     // Compute the tensor size from the shape.
-    int64_t const_coeff = dtype.bytes() * dtype.lanes();
+    int64_t const_coeff = ((((dtype).bits * 
static_cast<int16_t>((dtype).lanes)) + 7) / 8);

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   We should use the `PrimType` wrapper to safely retrieve the lanes and bits, 
and explicitly check that it is not a scalable vector to prevent 
negative/overflowed size calculations.
   
   ```c
     explicit StorageToken(ffi::Array<PrimExpr> shape, DLDataType dtype, 
std::string storage_scope,\n                        ffi::Optional<VDevice> 
vdevice = std::nullopt) {\n    // Compute the tensor size from the shape.\n    
PrimType prim_type(dtype);\n    TVM_FFI_ICHECK(!prim_type.IsScalableVector())\n 
       << "Cannot allocate storage for scalable vector dtype at compile 
time.";\n    int64_t const_coeff = (prim_type.bits() * prim_type.lanes() + 7) / 
8;
   ```



##########
src/s_tir/analysis/verify_gpu_code.cc:
##########
@@ -202,38 +204,50 @@ class GPUCodeVerifier : public StmtExprVisitor {
   void CheckBufferIndicesVectorizable(const ffi::Array<PrimExpr> indices) {
     for (const auto index : indices) {
       if (const auto* ramp = index.as<RampNode>()) {
-        if (!is_one(ramp->stride) &&
-            static_cast<size_t>(ramp->dtype.lanes() * ramp->dtype.bytes()) > 
max_vector_bytes_) {
+        PrimType ramp_ty = ramp->ty();
+        DLDataType ramp_dtype = ramp_ty->dtype;
+        if (!is_one(ramp->stride) && ramp_ty.IsFixedLengthVector() &&

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   We can simplify this by using `ramp_ty.lanes()` and `ramp_ty.bits()` 
directly instead of unpacking to `DLDataType` and performing manual bit/lane 
arithmetic.
   
   ```c
           PrimType ramp_ty = ramp->ty();\n        if (!is_one(ramp->stride) && 
ramp_ty.IsFixedLengthVector() &&\n            
static_cast<size_t>(ramp_ty.lanes() * ((ramp_ty.bits() + 7) / 8)) > 
max_vector_bytes_) {
   ```



##########
src/s_tir/analysis/verify_gpu_code.cc:
##########
@@ -202,38 +204,50 @@ class GPUCodeVerifier : public StmtExprVisitor {
   void CheckBufferIndicesVectorizable(const ffi::Array<PrimExpr> indices) {
     for (const auto index : indices) {
       if (const auto* ramp = index.as<RampNode>()) {
-        if (!is_one(ramp->stride) &&
-            static_cast<size_t>(ramp->dtype.lanes() * ramp->dtype.bytes()) > 
max_vector_bytes_) {
+        PrimType ramp_ty = ramp->ty();
+        DLDataType ramp_dtype = ramp_ty->dtype;
+        if (!is_one(ramp->stride) && ramp_ty.IsFixedLengthVector() &&
+            static_cast<size_t>(static_cast<int16_t>((ramp_dtype).lanes) *
+                                (((ramp_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {
           std::stringstream s;
-          s << "Number of lanes (" << ramp->dtype.lanes() << ") times number 
of bytes ("
-            << ramp->dtype.bytes() << ") for dtype " << ramp->dtype
-            << " is greater than the maximum number of vector bytes (" << 
max_vector_bytes_ << ")";
+          s << "Number of lanes (" << static_cast<int16_t>((ramp_dtype).lanes)
+            << ") times number of bytes (" << (((ramp_dtype).bits + 7) / 8) << 
") for dtype "
+            << ramp_dtype << " is greater than the maximum number of vector 
bytes ("
+            << max_vector_bytes_ << ")";
           errors_.push_back(s.str());
         }
       }
     }
   }
 
   void VisitExpr_(const CastNode* op) {
-    if (op->dtype.is_vector()) {
-      if (static_cast<size_t>(op->dtype.lanes() * op->dtype.bytes()) > 
max_vector_bytes_) {
+    PrimType op_ty = op->ty();
+    DLDataType op_dtype = op_ty->dtype;
+    if (op_ty.IsFixedLengthVector()) {
+      if (static_cast<size_t>(static_cast<int16_t>((op_dtype).lanes) *
+                              (((op_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {
         std::stringstream s;
-        s << "Number of lanes (" << op->dtype.lanes() << ") times number of 
bytes ("
-          << op->dtype.bytes() << ") for dtype " << op->dtype
-          << " is greater than the maximum number of vector bytes (" << 
max_vector_bytes_ << ")";
+        s << "Number of lanes (" << static_cast<int16_t>((op_dtype).lanes)
+          << ") times number of bytes (" << (((op_dtype).bits + 7) / 8) << ") 
for dtype "
+          << op_dtype << " is greater than the maximum number of vector bytes 
("
+          << max_vector_bytes_ << ")";
         errors_.push_back(s.str());
       }
     }
     ExprVisitor::VisitExpr_(op);
   }
 
   void VisitExpr_(const BufferLoadNode* op) {
-    if (op->dtype.is_vector()) {
-      if (static_cast<size_t>(op->dtype.lanes() * op->dtype.bytes()) > 
max_vector_bytes_) {
+    PrimType op_ty = op->ty();
+    DLDataType op_dtype = op_ty->dtype;
+    if (op_ty.IsFixedLengthVector()) {
+      if (static_cast<size_t>(static_cast<int16_t>((op_dtype).lanes) *
+                              (((op_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   We can simplify this by using `op_ty.lanes()` and `op_ty.bits()` directly 
instead of unpacking to `DLDataType` and performing manual bit/lane arithmetic.
   
   ```c
       PrimType op_ty = op->ty();\n    if (op_ty.IsFixedLengthVector()) {\n     
 if (static_cast<size_t>(op_ty.lanes() * ((op_ty.bits() + 7) / 8)) > 
max_vector_bytes_) {
   ```



##########
src/s_tir/analysis/verify_gpu_code.cc:
##########
@@ -242,13 +256,16 @@ class GPUCodeVerifier : public StmtExprVisitor {
   }
 
   void VisitStmt_(const BufferStoreNode* op) {
-    if (op->value->dtype.is_vector()) {
-      if (static_cast<size_t>(op->value->dtype.lanes() * 
op->value->dtype.bytes()) >
-          max_vector_bytes_) {
+    PrimType value_ty = op->value.ty();
+    DLDataType value_dtype = value_ty->dtype;
+    if (value_ty.IsFixedLengthVector()) {
+      if (static_cast<size_t>(static_cast<int16_t>((value_dtype).lanes) *
+                              (((value_dtype).bits + 7) / 8)) > 
max_vector_bytes_) {

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   We can simplify this by using `value_ty.lanes()` and `value_ty.bits()` 
directly instead of unpacking to `DLDataType` and performing manual bit/lane 
arithmetic.
   
   ```c
       PrimType value_ty = op->value.ty();\n    if 
(value_ty.IsFixedLengthVector()) {\n      if 
(static_cast<size_t>(value_ty.lanes() * ((value_ty.bits() + 7) / 8)) > 
max_vector_bytes_) {
   ```



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