ray-project / ray

Ray is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.
https://ray.io
Apache License 2.0
33.98k stars 5.77k forks source link

[core] Python class variables not updating between all remote instances of the class #12977

Open blueplastic opened 3 years ago

blueplastic commented 3 years ago

What is the problem?

It seems that Ray doesn't allow using a class variable to keep track of some shared class-level information, such as how many instances of the class have been created.

I understand there are at least a couple of ways I can accomplish sharing state across instances:

  1. I can use a different class with an counter instance variable and have all of the launched classes update that
  2. I could add the shared state in Ray's memory with ray.put()

But I was curious about class variable support in Ray. Should class variables simply not be used? Are there any best practices around sharing state across instances?

Class variables can also make it efficient to implement default values for instance variables while avoiding the time and memory overhead of initializing that instance variable every time a class instance is created. If class variables are not supported, do we have to incur the time/memory overhead for initializing each instance variable?

Ray version: 1.0.1.post1 Python version: 3.7.8

Reproduction

@ray.remote
class Circle():   
    numStarts = 0
    def __init__(self):
        Circle.numStarts += 1           
    def countStarts(self):
        return Circle.numStarts

c1 = Circle.remote()
c2 = Circle.remote()

#This returns 0, but 2 was expected
Circle.numStarts

# This raises "AttributeError: type object 'ActorHandle' has no attribute 'numStarts'", but 2 was expected
c1.__class__.numStarts

# This also raises an AttributeError. The class variable cannot be accessed as an instance variable
c1.numStarts

If the code snippet cannot be run by itself, the issue will be closed with "needs-repro-script".

edoakes commented 3 years ago

@blueplastic actor classes are instantiated across multiple processes, so each actor will have its own copy of the class variables. Therefore, using class variables is not currently supported/recommended.

We should definitely try to raise an informative error message here, though.

rkooo567 commented 3 years ago

https://docs.google.com/document/d/167rnnDFIVRhHhK4mznEIemOtj63IOhtIPvSYaPgI4Fg/edit#heading=h.eg7m6lz2y48u

This document could be related

ofey404 commented 2 years ago

What if raising an exception when user is trying to define a class variable?

It may not be a good idea, because it breaks backward compatibility - someone may already using class variable in workers as a feature.

zw0610 commented 1 year ago

What if raising an exception when user is trying to define a class variable?

It may not be a good idea, because it breaks backward compatibility - someone may already using class variable in workers as a feature.

exactly. maybe introducing a global (in the concept of ray instead of python) variable decorator to the class variable would make more sense.