问题
I have a script that looks like a more complicated version of this:
import ray
var1 = 0
var2 = 0
@ray.remote
def create(n):
global var1
global var2
for i in range(10):
var1 += 1
var2 += 1
def create2():
tasks = [create.remote(i) for i in range(20)]
ray.get(tasks)
create2()
This errors because Ray does not allow global variables to be used in the traditional way. How can I get around this?
回答1:
Q : "How can I get around this?"
One solution would be to create a method .add1()
for either of quasi-global
-s, the implementation of which will deliver a request to add 1 to the main
.
This way the main
is able to maintain a cheapest ( not overly expensive ) atomicity of incrementing any quasi-global
, due to an enforced [SERIAL]
-signal processing of otherwise principally [CONCURRENT]
-signal arrival(s).
Possible vehicles for doing that are ZeroMQ PUSH/PULL
and nanomsg
or pynng push/pull
Scalable Formal Communication Pattern archetypes.
In case one has never worked with ZeroMQ,
one may here enjoy to first look at "ZeroMQ: Principles in less than Five Seconds"
before diving into further details
Each @ray.remote
-decorated execution may setup its own { PUSH | push }
-side of the signalling path, whereas the main
-side or its { thread | process }-based spin-off just populates a central { PULL | pull }
-side, located at a constant .bind( <Transport_Class>:<Port#orOtherAdressSpecifier> )
"collection-service" location. Each of the PUSH
-ers .connect()
to that a priori known TransportClass target-address and the rest is trivial.
Using more robust, error-resilient methods is also possible, depends on your needs. So no global
-s needed for doing this or more complex any:M+N
-resilient voting-, collector- or generic multi-agent distributed signalling.
Cool. Isn't it?
回答2:
You can create an actor that holds the variables and update it.
@ray.remote
class GlobalState:
def __init__(self):
self.state = {
"var1": 0,
"var2": 0
}
def increment(key):
self.state[key] += 1
@ray.remote
def create(global_state):
for i in range(10):
global_state.increment.remote("var1")
global_state.increment.remote("var2")
def create2(global_state):
tasks = [create.remote(global_state) for i in range(20)]
ray.get(tasks)
global_state = GlobalState.remote()
create2(global_state)
来源:https://stackoverflow.com/questions/62640533/how-to-use-global-variables-with-ray