Ask actors to share resources, without deadlocking

Assume I have 4 actors, each requiring 2 CPUs to run a task (8 CPUs required in total) .

When doing ray.init, I request to use 4 CPUs only.

So there is not enough CPUs to run the tasks simultaneously.

How to ask the 4 actors to share the resources, i.e., execute 2 tasks at a time, instead of 4?

The following code does what I described:

import ray
import time

@ray.remote(num_cpus=2)  # say each actor requires 2 cpus 
class MyActor:
    def run_task(self, value):
        time.sleep(1)
        return value

ray.init(num_cpus=4)  # we request 4 cpus only
actors = [MyActor.remote() for _ in range(4)] # and  we have 4 actors, each requiring 2 cpus

res_ids = [a.run_task.remote(v) for a,  v  in zip(actors, range(4))]

print(ray.get(res_ids))

ray.shutdown()

However, the above code produces resource deadlock, i.e.,:

(scheduler +28s) Warning: The following resource request cannot be scheduled right now: {'CPU': 2.0}. This is likely due to all c\
luster resources being claimed by actors. Consider creating fewer actors or adding more nodes to this Ray cluster.
2021-11-16 13:27:42,860 WARNING worker.py:1228 -- The actor or task with ID ffffffffffffffff3855cc574aa230e3821355a601000000 cann\
ot be scheduled right now. You can ignore this message if this Ray cluster is expected to auto-scale or if you specified a runtim\
e_env for this actor or task, which may take time to install.  Otherwise, this is likely due to all cluster resources being claim\
ed by actors. To resolve the issue, consider creating fewer actors or increasing the resources available to this Ray cluster.
Required resources for this actor or task: {CPU: 2.000000}

Note that this post is a simplified version of a previous one

I managed to have a “actor-free” solution. The main idea is to use remote functions instead of actors. See more details at this post.

What about

MyACtor.options(num_cpus=1).remote()

?