Python:* args和远程函数中的列表之间的区别

时间:2019-01-21 00:45:18

标签: python synchronization ray

定义列表

g = [1, 2, 3, 4]

版本1

@ray.remote
def f(*g):     
    return np.mean(g, axis=0)
f_ids = [f.remote(*g) for _ in range(10)]
print(ray.get(f.remote(*f_ids)))

版本2

@ray.remote
def f(g):    # g is object ID list
    return np.mean(g, axis=0)
f_ids = [f.remote(g) for _ in range(10)]
print(ray.get(f.remote(f_ids)))

第一个代码可以正常工作,但是第2版不起作用。错误消息是

  

ray.get(f.remote(f_ids))   +不支持的操作数类型:“ common.ObjectID”和“ common.ObjectID”

我想做类似Version 2的原因是我实际上想做类似以下的事情

@remote
def f(g1, g2):    # g1 and g2 are object ID lists
    ...           # do something here

我不知道如何将g1g2设置为*g1*g2,所以我提到了版本2。为什么版本2不起作用?我该如何解决?

参考代码在这里 https://ray.readthedocs.io/en/latest/example-parameter-server.html#synchronous-parameter-server

1 个答案:

答案 0 :(得分:1)

将参数传递到Ray远程函数中时,类型为ray.ObjectID的任何参数都将自动由解压后的值替换(这意味着ray.get在后​​台被调用)。其他所有参数均不变。

这就是为什么如果您定义了像这样的远程功能

# Assuming you already called "import ray" and "ray.init()".

@ray.remote
def g(x):
    print(x)

您会看到的

g.remote(1)  # This prints '1'
g.remote(ray.put(1))  # This also prints '1'
g.remote([ray.put(1)])  # This prints '[ObjectID(feffffffe3f2116088b37cb305fbb2537b9783ee)]'

在第三行中,由于参数是一个列表,因此列表内的ObjectID不会被其对应的值替换。

在您的示例中,您有

@ray.remote
def f(*xs):
    print(xs)

您的版本1 版本2 之间的区别在于,在版本1 中,您要传递多个ObjectID论点。在版本2 中,您传入一个参数,该参数是包含多个ObjectID的列表。

xs = [ray.put(1), ray.put(2)]
f.remote(*xs)  # This prints '(1, 2)'
f.remote(xs)  # This prints '([ObjectID(fcffffffe3f2116088b37cb305fbb2537b9783ee), ObjectID(fbffffffe3f2116088b37cb305fbb2537b9783ee)],)'

要执行所需的操作,您可能需要执行以下操作(实质上是将两个列表合并为一个)。它不是最漂亮,但应该可以。

@ray.remote
def h(num_xs, *xs_and_ys):
    xs = xs_and_ys[:num_xs]
    ys = xs_and_ys[num_xs:]
    print(xs, ys)

x_ids = [ray.put(1), ray.put(2)]
y_ids = [ray.put(3), ray.put(4), ray.put(5)]

h.remote(len(x_ids), *(x_ids + y_ids))  # This prints '(1, 2) (3, 4, 5)'