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


##########
python/tvm/relax/frontend/onnx/onnx_frontend.py:
##########
@@ -3893,6 +3893,117 @@ def _impl_v23(cls, bb, inputs, attr, params):
         return output
 
 
+class GroupNormalization(OnnxOpConverter):
+    """Converts an onnx GroupNormalization node into an equivalent Relax 
expression"""
+
+    @classmethod
+    def _impl_v18(cls, bb, inputs, attr, params):
+        data = inputs[0]
+        scale = inputs[1]
+        bias = inputs[2]

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   We can use `get_constant` to resolve `scale` and `bias` to constants if they 
are initializers. This allows us to perform the per-group to per-channel 
expansion at import time using NumPy, avoiding redundant `reshape` and 
`broadcast_to` operators in the Relax graph.
   
   ```suggestion
           data = inputs[0]
           scale = get_constant(inputs[1], params)
           bias = get_constant(inputs[2], params)
   ```



##########
python/tvm/relax/frontend/onnx/onnx_frontend.py:
##########
@@ -3893,6 +3893,117 @@ def _impl_v23(cls, bb, inputs, attr, params):
         return output
 
 
+class GroupNormalization(OnnxOpConverter):
+    """Converts an onnx GroupNormalization node into an equivalent Relax 
expression"""
+
+    @classmethod
+    def _impl_v18(cls, bb, inputs, attr, params):
+        data = inputs[0]
+        scale = inputs[1]
+        bias = inputs[2]
+        num_groups = attr["num_groups"]
+        epsilon = attr.get("epsilon", 1e-05)
+
+        ndim = _get_known_tensor_rank(data)
+        if ndim is None:
+            raise ValueError("GroupNormalization requires a statically known 
input rank.")
+
+        ty = data.ty
+        if not isinstance(ty, relax.TensorType) or len(ty.shape) < 2:
+            raise ValueError(
+                "GroupNormalization-18 requires a statically typed input with 
rank >= 2."
+            )
+
+        if num_groups <= 0:
+            raise ValueError(
+                f"GroupNormalization requires num_groups to be positive, got 
{num_groups}."
+            )
+
+        channel_dim = ty.shape[1]
+        if not isinstance(channel_dim, tirx.IntImm):
+            raise ValueError(
+                "GroupNormalization-18 requires a statically known channel 
count "
+                "to expand per-group scale/bias to per-channel."
+            )
+
+        channels = int(channel_dim)
+        if channels % num_groups != 0:
+            raise ValueError(
+                f"GroupNormalization requires num_groups to divide channel 
count, "
+                f"but got C={channels} and num_groups={num_groups}."
+            )
+
+        channels_per_group = channels // num_groups
+
+        scale = relax.op.reshape(scale, [num_groups, 1])
+        scale = relax.op.broadcast_to(scale, [num_groups, channels_per_group])
+        scale = relax.op.reshape(scale, [channels])
+
+        bias = relax.op.reshape(bias, [num_groups, 1])
+        bias = relax.op.broadcast_to(bias, [num_groups, channels_per_group])
+        bias = relax.op.reshape(bias, [channels])

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   If `scale` and `bias` are resolved to constants, we can expand them directly 
using `_np.repeat` at import time. This simplifies the generated Relax graph by 
eliminating unnecessary `reshape` and `broadcast_to` operations.
   
   ```suggestion
           if isinstance(scale, relax.Constant):
               scale = relax.const(_np.repeat(scale.data.numpy(), 
channels_per_group), scale.ty.dtype)
           else:
               scale = relax.op.reshape(scale, [num_groups, 1])
               scale = relax.op.broadcast_to(scale, [num_groups, 
channels_per_group])
               scale = relax.op.reshape(scale, [channels])
   
           if isinstance(bias, relax.Constant):
               bias = relax.const(_np.repeat(bias.data.numpy(), 
channels_per_group), bias.ty.dtype)
           else:
               bias = relax.op.reshape(bias, [num_groups, 1])
               bias = relax.op.broadcast_to(bias, [num_groups, 
channels_per_group])
               bias = relax.op.reshape(bias, [channels])
   ```



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