code: def parallel(devices, fn, *args, **kwargs):
    
    if not isinstance(devices, list):
      raise ValueError("devices must be a list")
    for x in list(args) + list(six.itervalues(kwargs)):
      if not isinstance(x, list) or len(x) != len(devices):
        raise ValueError(
            "Argument not a list with same length as devices "
            "arg=%s devices=%s" % (x, devices))
    ret = []
    for i, device in enumerate(devices):
      with tf.device(device):
        with tf.variable_scope("parallel_%d" % i):
          my_args = [x[i] for x in args]
          my_kwargs = {k: v[i] for k, v in six.iteritems(kwargs)}
          ret.append(fn(*my_args, **my_kwargs))
    return ret
docs: Call a function once on each device.
  
    Args:
      devices: a list of n devices
      fn: a function
      *args: arguments, each of which is a list of length n
      **kwargs: keyword-args, each of which is a list of length n
    Returns:
      a list of length n
    Raises:
      ValueError: if the arguments are not all lists of length n