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


##########
python/tvm/relax/frontend/torch/exported_program_translator.py:
##########
@@ -918,6 +918,189 @@ def _gru(self, node: fx.Node) -> relax.Var:
 
         return output
 
+    def _rnn_tanh_cell_unroll(
+        self,
+        input_reshaped,
+        weight_ih,
+        weight_hh,
+        bias_ih,
+        bias_hh,
+        h_prev,
+        seq_len,
+        reverse=False,
+    ):
+        """Unroll vanilla tanh-RNN cells for a single direction."""
+        # Transpose weights for matmul: (hidden_size, in) -> (in, hidden_size)
+        weight_ih_t = self.block_builder.emit(relax.op.permute_dims(weight_ih, 
axes=[1, 0]))
+        weight_hh_t = self.block_builder.emit(relax.op.permute_dims(weight_hh, 
axes=[1, 0]))
+
+        outputs = []
+        time_steps = range(seq_len - 1, -1, -1) if reverse else range(seq_len)
+
+        for t in time_steps:
+            # Input at time t: (batch_size, input_size)
+            x_t = self.block_builder.emit(
+                relax.op.take(input_reshaped, relax.const(t, "int64"), axis=0, 
mode="clip")
+            )
+
+            # h_t = tanh(W_ih @ x_t + b_ih + W_hh @ h_{t-1} + b_hh)
+            ih = self.block_builder.emit(relax.op.linear_algebra.matmul(x_t, 
weight_ih_t))
+            hh = 
self.block_builder.emit(relax.op.linear_algebra.matmul(h_prev, weight_hh_t))
+            if bias_ih is not None and bias_hh is not None:
+                ih = self.block_builder.emit(relax.op.add(ih, bias_ih))
+                hh = self.block_builder.emit(relax.op.add(hh, bias_hh))
+            h_t = self.block_builder.emit(relax.op.tanh(relax.op.add(ih, hh)))
+
+            outputs.append(h_t)
+            h_prev = h_t

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Since `bias_ih` and `bias_hh` are constant across all time steps, we can 
pre-compute their sum `bias = bias_ih + bias_hh` outside the loop. This avoids 
performing `seq_len` redundant additions and emitting unnecessary intermediate 
variables in the Relax block for each time step.
   
   ```python
           bias = None
           if bias_ih is not None and bias_hh is not None:
               bias = self.block_builder.emit(relax.op.add(bias_ih, bias_hh))
   
           outputs = []
           time_steps = range(seq_len - 1, -1, -1) if reverse else 
range(seq_len)
   
           for t in time_steps:
               # Input at time t: (batch_size, input_size)
               x_t = self.block_builder.emit(
                   relax.op.take(input_reshaped, relax.const(t, "int64"), 
axis=0, mode="clip")
               )
   
               # h_t = tanh(W_ih @ x_t + W_hh @ h_{t-1} + bias)
               ih = self.block_builder.emit(relax.op.linear_algebra.matmul(x_t, 
weight_ih_t))
               hh = 
self.block_builder.emit(relax.op.linear_algebra.matmul(h_prev, weight_hh_t))
               ih_hh = self.block_builder.emit(relax.op.add(ih, hh))
               if bias is not None:
                   ih_hh = self.block_builder.emit(relax.op.add(ih_hh, bias))
               h_t = self.block_builder.emit(relax.op.tanh(ih_hh))
   
               outputs.append(h_t)
               h_prev = h_t
   ```



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