列表不会因为Ray并行python而改变。

问题描述 投票:0回答:1

我的问题是,如果我重新分配列表中的一个项目,使其在并行过程中发生重新分配,那么在并行过程结束后,该变化会恢复到其原始状态。

在下面的例子中--为了便于理解而大大简化--我有一个函数将列表元素NoZeros[0]改为 "chicken",第二个函数将NoZeros[1]改为 "sandwich"。我甚至在第二个函数中加入了 "全局",只是为了证明这不是一个局部与全局的问题--它看起来像一个问题,但它确实不是。当你运行程序时,打印命令会告诉你,列表元素确实发生了变化。问题是在这些过程之后调用NoZeros时,NoZeros还是原来的样子,而不是"["鸡肉","三明治"]。

我知道python的多进程包也有一模一样的问题,但解决的方法是把你想不还原的东西 "一步到位",然后在它之前的地方贴上 "manager.list()"。我的问题是,我一辈子都搞不清楚雷的等价物是什么。例如,在Python的多处理库中,你只需要在NoZeros被改变之前的某个地方写NoZeros=manager.list(NoZeros),这就结束了,但我找不到Ray的等价物,或者是否有等价物。

如何使用RAY在parallel中改变列表?非常感谢。

另外:请注意这个脚本可能会让你陷入一个循环,因为你可能会在并行进程完成之前打印NoZeros。这是我遇到的另一个bug,希望得到关注,但这不是优先级。我想说的是,你可能想在下一个单元格中运行print(NoZeros)(至少Jupyter有这个功能)。在 python 的多处理库中,我们只需执行 "process.join()",就能解决结束相关进程的问题,所以这让我想到了额外的问题。

额外的问题: 如何让ray.wait()工作;如何告诉我的代码只有在前面的命令--即使是并行命令--完成后,才会进入下一个命令?

'''

import ray

ray.shutdown()
ray.init()

NoZeros=[0,0]

@ray.remote
def Chicken():
    print("NoZeros[0] is",NoZeros[0],"but will change to chicken")
    NoZeros[0]="chicken"
    print("Now, NoZeros[0] is",NoZeros[0])


@ray.remote
def GlobalSandwich():
    global NoZeros #This is just to show that "global" doesn't solve anything
    print("NoZeros[1] is",NoZeros[1],"but will change to sandwich")
    NoZeros[1]="sandwich"
    print("Now, NoZeros[1] is",NoZeros[1])

Chicken.remote()
GlobalSandwich.remote()

#Unhash these 3 lines of code if youd like to try tackling another question: why does ray.wait() not work? 
#How do i wait until parallel processes end, so i can continue my code?

#WaitList=[Chicken.remote(),GlobalSandwich.remote()]
#ray.wait(WaitList)
#print("If you see this first, ray.wait() isnt working")


#This line of code right here was executed in the next command line (Jupyter); this print command happens when the other processes are finished  
print(NoZeros)

'''

list indexing parallel-processing assign ray
1个回答
0
投票

在Ray中,可变的全局状态应该存在于 演员. 例如,你可以做这样的事情。

@ray.remote
class ListActor:
    def __init__(self, l):
        self._list = l

    def get(self, i):
        return self._list[i]

    def set(self, i, val):
        self._list[i] = val

    def to_list(self):
        return self._list

然后为了使用它,你可以把它作为一个参数传递进去(同样,你不应该依赖全局变量)。

NoZeros = ListActor.remote([0,0])

@ray.remote
def Chicken(NoZeros):
    print("NoZeros[0] is",ray.get(NoZeros.get.remote(0)),"but will change to chicken")
    NoZeros.set(0, "chicken")
    print("Now, NoZeros[0] is",ray.get(NoZeros.get(0)))


# We need to make sure this function finishes executing before we print.
ray.get(Chicken.remote(NoZeros))

print(ray.get(NoZeros.to_list.remote()))
© www.soinside.com 2019 - 2024. All rights reserved.