code: def test_unit_norm(self, device, dtype, batch_size):
      q1 = Quaternion.random(batch_size, device, dtype)
      q2 = Quaternion.random(batch_size, device, dtype)
      s1 = So3(q1)
      s2 = So3(q2)
      s3 = s1 * s2
      s4 = s1.inverse()
      s5 = s2.inverse()
      s6 = s3.inverse()
  
      ones_vec = torch.tensor(1.0, device=device, dtype=dtype)
      if batch_size is None:
          self.assert_close(s1.q.norm(), ones_vec)
          return
  
      for i in range(batch_size):
          self.assert_close(s1[i].q.norm(), ones_vec)
          self.assert_close(s2[i].q.norm(), ones_vec)
          self.assert_close(s3[i].q.norm(), ones_vec)
          self.assert_close(s4[i].q.norm(), ones_vec)
          self.assert_close(s5[i].q.norm(), ones_vec)
          self.assert_close(s6[i].q.norm(), ones_vec)
  
imports: import pytest
  import torch
  from kornia.geometry.conversions import euler_from_quaternion
  from kornia.geometry.liegroup import So3
  from kornia.geometry.quaternion import Quaternion
  from kornia.geometry.vector import Vector3
  from kornia.testing import BaseTester
label_desc: Use image node_id 12 for calling the TestSo3 obj's underlying member method code with example usage: obj.test_unit_norm(device, dtype, batch_size) without return types