11thal11thal
11thal11thal

Reputation: 333

How to use global variables with Ray

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?

Upvotes: 2

Views: 2526

Answers (2)

user3666197
user3666197

Reputation: 1

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.

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.

Upvotes: 1

Sang
Sang

Reputation: 925

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)

Upvotes: 2

Related Questions