Списки не изменятся с Ray parallel python - PullRequest
0 голосов
/ 16 июня 2020

Моя проблема в том, что если я переназначаю элемент в списке так, что переназначение происходит во время параллельного процесса, то после завершения параллельных процессов изменение возвращается в исходное состояние.

В приведенном ниже примере - сильно упрощенном для простоты понимания - у меня есть функция, которая меняет элемент списка NoZeros [0] на «курицу», и вторая функция, которая меняет NoZeros [1] на «бутерброд». . Я даже добавил «global» во вторую функцию, чтобы продемонстрировать, что это не проблема локального и глобального характера - похоже, что это так, но на самом деле это не так. Как показывают команды печати при запуске программы, элементы списка действительно меняются. Проблема в том, что при вызове NoZeros после этих процессов, NoZeros - это то, с чего он был изначально, вместо «[" курица "," бутерброд "].

Я знаю, что пакет многопроцессорной обработки python точно содержит та же проблема, но она была решена, сделав «один шаг вперед» того, к чему вы не хотели возвращаться, и ударив по «manager.list ()» перед этим. Моя проблема в том, что я не могу жизнь меня выяснила, что эквивалентно для Рэя. Например, в библиотеке многопроцессорной обработки Python, вы бы просто написали NoZeros = manager.list (NoZeros) где-нибудь до того, как NoZeros будет изменен, и это будет конец , но я не могу найти, какой есть эквивалент для Ray или есть ли вообще эквивалент.

КАК ИЗМЕНИТЬ СПИСКИ ПАРАЛЛЕЛЬНО, ИСПОЛЬЗУЯ RAY? Большое спасибо.

Также: обратите внимание, что этот сценарий может бросить вас за al oop, потому что вы можете в конечном итоге распечатать NoZeros ДО завершения параллельных процессов sh. Это еще одна ошибка, с которой у меня проблемы, и я буду благодарен за внимание п, но это не приоритет. Я хочу сказать, что вы, вероятно, захотите запустить печать (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)

' ''

1 Ответ

0 голосов
/ 17 июня 2020

С 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()))
...