What is Ray Core?

Ray Core provides a small number of core primitives (i.e., tasks, actors, objects) for building and scaling distributed applications. Below we’ll walk through simple examples that show you how to turn your functions and classes easily into Ray tasks and actors, and how to work with Ray objects.

Getting Started

To get started, install Ray via pip install -U ray. See Installing Ray for more installation options. The following few sections will walk through the basics of using Ray Core.

The first step is to import and initialize Ray:

import ray

ray.init()

Note

In recent versions of Ray (>=1.5), ray.init() is automatically called on the first use of a Ray remote API.

Running a Task

Ray lets you run functions as remote tasks in the cluster. To do this, you decorate your function with @ray.remote to declare that you want to run this function remotely. Then, you call that function with .remote() instead of calling it normally. This remote call yields a future, a so-called Ray object reference, that you can then fetch with ray.get:

# Define the square task.
@ray.remote
def square(x):
    return x * x

# Launch four parallel square tasks.
futures = [square.remote(i) for i in range(4)]

# Retrieve results.
print(ray.get(futures))
# -> [0, 1, 4, 9]

Calling an Actor

Ray provides actors to allow you to parallelize computation across multiple actor instances. When you instantiate a class that is a Ray actor, Ray will start a remote instance of that class in the cluster. This actor can then execute remote method calls and maintain its own internal state:

# Define the Counter actor.
@ray.remote
class Counter:
    def __init__(self):
        self.i = 0

    def get(self):
        return self.i

    def incr(self, value):
        self.i += value

# Create a Counter actor.
c = Counter.remote()

# Submit calls to the actor. These calls run asynchronously but in
# submission order on the remote actor process.
for _ in range(10):
    c.incr.remote(1)

# Retrieve final actor state.
print(ray.get(c.get.remote()))
# -> 10

The above covers very basic actor usage. For a more in-depth example, including using both tasks and actors together, check out Monte Carlo Estimation of π.

Passing an Object

As seen above, Ray stores task and actor call results in its distributed object store, returning object references that can be later retrieved. Object references can also be created explicitly via ray.put, and object references can be passed to tasks as substitutes for argument values:

import numpy as np

# Define a task that sums the values in a matrix.
@ray.remote
def sum_matrix(matrix):
    return np.sum(matrix)

# Call the task with a literal argument value.
print(ray.get(sum_matrix.remote(np.ones((100, 100)))))
# -> 10000.0

# Put a large array into the object store.
matrix_ref = ray.put(np.ones((1000, 1000)))

# Call the task with the object reference as an argument.
print(ray.get(sum_matrix.remote(matrix_ref)))
# -> 1000000.0

Next Steps

Ray’s key primitives are simple, but can be composed together to express almost any kind of distributed computation. Learn more about Ray’s key concepts with the following user guides: