<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def grad_dot(dy, x1, x2):
 """Gradient of NumPy dot product w.r.t. to the left hand side. Args: dy: The gradient with respect to the output. x1: The left hand side of the `numpy.dot` function. x2: The right hand side Returns: The gradient with respect to `x1` i.e. `x2.dot(dy.T)` with all the broadcasting involved. """

  if len(numpy.shape(x1)) == 1:
    dy = numpy.atleast_2d(dy)
  elif len(numpy.shape(x2)) == 1:
    dy = numpy.transpose(numpy.atleast_2d(dy))
    x2 = numpy.transpose(numpy.atleast_2d(x2))
  x2_t = numpy.transpose(numpy.atleast_2d(
      numpy.sum(x2, axis=tuple(numpy.arange(numpy.ndim(x2) - 2)))))
  dy_x2 = numpy.sum(dy, axis=tuple(-numpy.arange(numpy.ndim(x2) - 2) - 2))
  return numpy.reshape(numpy.dot(dy_x2, x2_t), numpy.shape(x1))