1

Is

@ray.remote
def run_experiment(...):

(...)

if __name__ == '__main__':
    ray.init()

    exp_config = sys.argv[1]
    params_tuples, num_cpus, num_gpus = load_exp_config(exp_config)

    ray.get([run_experiment.options(num_cpus=num_cpus,
                                    num_gpus=num_gpus).remote(*args) for args in params_tuples])

perfectly equivalent to :

@ray.remote(num_cpus=num_cpus, num_gpus=num_gpus)
def run_experiment(...):

(...)

if __name__ == '__main__':
    ray.init()

    exp_config = sys.argv[1]
    params_tuples, _, _ = load_exp_config(exp_config)

    ray.get([run_experiment.remote(*args) for args in params_tuples])

when it comes to ray resources configuration ? Just in case for context : this is run on a Slurm cluster node (typically to take advantage of large GPUs to run parallel "small" experiments on a single node).

4
  • It's pretty clear from the manual that what you set via .options() simply overrides what you gave in the decorator, so yes, using one or the other should do the same thing. Did you give it a try? What results did you get? Were there any errors or unexpected results? Commented Nov 10 at 18:36
  • I did try it on a cluster node possibly poorly configured and therefore wanted to make sure I used these parameters properly to eliminate the possibility of the latter being the origin of issues. Commented Nov 11 at 22:26
  • How do you define "perfectly equivalent" in your case? You do not get the same object back but one that is very similar in effect. From the scheduling effect you should get the same result Commented Nov 12 at 16:28
  • That would be fine (and thus "equivalent") for me :) Commented Nov 18 at 13:05

1 Answer 1

0

From functionality it is equivalent - you end up with slightly different wrapped objects when you use .options, that is afterwards you only have remote (and bind) as callable methods.

Lets go step by step. With using ray.remote you end up either with a RemoteFunction or an ActorClass. For both the important part is their private function _remote (see 1, 2 or their remote implementation) which takes the options as keyword arguments and is the core implementation.

Calling the "normal" remote is executed as:
self._remote(args=args, kwargs=kwargs, **self._default_options)

If you use .options you get a wrapper class with its own options, for their case _remote is executed as: actor_cls._remote(args=args, kwargs=kwargs, **updated_options). (See 3, 4) Where updated_options is the merge from the original with the new ones you provided in options. Both operate on the same original object (actor_cls) just with different arguments, i.e.the original or merged options.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I accepted your answer. One or two URLs to the code, assuming the latter are available, could be nice to support the technical points made.
Yes you're totally right I've added links to the relevant source point. I was inspecting it locally on my fork.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.