I tried this operation for one batch and worked.
x = torch.FloatTensor([[ax,bx],[cx,dx],[ex,fx],[gx,hx]])
y = torch.FloatTensor([[ay,by],[cy,dy],[ey,fy],[gy,hy]])
z = x[:,None,0] * y[:,1]

print(z)

tensor([[ ax*by,  ax*dy,  ax*fy,  ax*hy],
        [ cx*by,  cx*dy,  cx*fy,  cx*hy],
        [ ex*by,  ex*dy,  ex*fy,  ex*hy],
        [ gx*by,  gx*dy,  gx*fy,  gx*hy]])

I want to repeat above operation for several batches like below example without using for loop.
x = torch.FloatTensor([[[ax1,bx1],[cx1,dx1],[ex1,fx1],[gx1,hx1]],
                       [[ax2,bx2],[cx2,dx2],[ex2,fx2],[gx2,hx2]]])
y = torch.FloatTensor([[[ay1,by1],[cy1,dy1],[ey1,fy1],[gy1,hy1]],
                       [[ay2,by2],[cy2,dy2],[ey2,fy2],[gy2,hy2]]])

This is what I want to get for result.
tensor([[[ ax1*by1,  ax1*dy1,  ax1*fy1,  ax1*hy1],
         [ cx1*by1,  cx1*dy1,  cx1*fy1,  cx1*hy1],
         [ ex1*by1,  ex1*dy1,  ex1*fy1,  ex1*hy1],
         [ gx1*by1,  gx1*dy1,  gx1*fy1,  gx1*hy1]],

        [[ ax2*by2,  ax2*dy2,  ax2*fy2,  ax2*hy2],
         [ cx2*by2,  cx2*dy2,  cx2*fy2,  cx2*hy2],
         [ ex2*by2,  ex2*dy2,  ex2*fy2,  ex2*hy2],
         [ gx2*by2,  gx2*dy2,  gx2*fy2,  gx2*hy2]]])

I tried as below, but gave me errors
z = x[...,None,0] * y[...,1]
RuntimeError: The size of tensor a (4) must match the size of tensor b (2) at non-singleton dimension 1

Is there any way doing this without for loop?