Skip to main content

Getting Started

Hello and welcome! This guide will help you dive right in and get your first workflow up and running in no time. Let's go!

Step 1: Sign Up

Create your account at Covalent. Once done, grab your API key from the dashboard. This is your personal access code to all of Covalent's fantastic features.

Step 2: Install The Python SDK

Install Covalent Cloud with the following command.

pip install covalent-cloud --upgrade

To get started, simply import covalent_cloud in your local development setup, whether in an IDE or a Jupyter Notebook and save your API key (from the previous step) following the example below.

import covalent_cloud as cc
cc.save_api_key("YOUR_API_KEY")

Step 3: Define Your Environments

Environments represent the libraries and packages your computations need. Let's set them up. This is a one-time process; you can always refer to environments by name later in your code.

cc.create_env("numpy_env", pip=["numpy"], conda=["python=3.9", "pip"])
cc.create_env("interp_env", pip=["scipy", "plotly"], conda=["python=3.9", "pip"])

Notice that the conda requirements include "python=3.9". This will be the Python version in the remote environment. We can specify any version here as long as we dispatch the workflow from a local environment using the same Python version.

Step 4: Define Your Executors

Executors manage the computational resources required for your tasks. Here, we are setting up two executors with two different sets of resources.

low_compute = cc.CloudExecutor(env="numpy_env", num_cpus=1, memory="1GB")
general_compute = cc.CloudExecutor(env="interp_env", num_cpus=4, memory="8GB")

Tip

To access GPUs, pass a num_gpus value greater than 0 and specify the gpu_type. For example, to access two H100 GPUs:

gpu_compute = cc.CloudExecutor(env="numpy_env", num_cpus=8, num_gpus=2, gpu_type="h100", memory="24GB")

See here for all available GPU types.

Step 5: Define Your Computations

Having set up our environments and executors, we define our computations using the @ct.electron decorator to create workflow tasks.

import numpy as np
import plotly.graph_objects as go
from scipy.interpolate import CubicSpline

import covalent as ct

@ct.electron(executor=low_compute)
def rand_sin_func(x):
n_waves = np.random.randint(1, 10)
amps = 10 * np.random.rand(n_waves)
phis = 2 * np.pi * np.random.rand(n_waves)
y = 0.0
for i in range(n_waves):
y += amps[i] * np.sin((i + 1) * x + phis[i])
return y

@ct.electron(executor=general_compute)
def get_spline(x, y, n_pts=1000):
cs = CubicSpline(x, y)
new_x = np.linspace(x.min(), x.max(), n_pts)
return np.asarray(cs(new_x))

@ct.electron(executor=general_compute)
def plot_interpolation(x, y, new_y, fig=None, label_i=1):
new_x = np.linspace(x.min(), x.max(), len(new_y))
fig = fig or go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='markers', name=f'Original({label_i})'))
fig.add_trace(go.Scatter(x=new_x, y=new_y, mode='lines', name=f'Interpolated({label_i})'))
fig.update_layout(
title="Random Sinusoid Interpolations",
xaxis_title="x",
yaxis_title="y",
)
return fig

Step 6: Create Your Workflow

Then, using the @ct.lattice decorator, we bring our tasks together into a workflow.

@ct.lattice(executor=general_compute, workflow_executor=general_compute)
def workflow(num_curves):
x = np.linspace(0, 2 * np.pi)
fig = None
for i in range(num_curves):
y = rand_sin_func(x)
y_spline = get_spline(x, y)
fig = plot_interpolation(x, y, y_spline, fig=fig, label_i=i + 1)
return fig

Warning

Unlike Open-Source, it is important to specify the lattice’s executor and workflow_executor parameters. Both of these must be cc.CloudExecutor instances.

Step 7: Dispatch Your Workflow and Get Results

Let's get the workflow in motion! To do this, we simply dispatch the workflow lattice.

dispatch_id = cc.dispatch(workflow)(num_curves=4)

Dispatching returns a string (dispatch_id) that uniquely identifies a given workflow. We can wait for the workflow to complete and then fetch its results any time thereafter with ct.get_result().

# Get ligthweight result reference.
result = cc.get_result(dispatch_id, wait=True)

# Download outputs.
result.result.load()

fig = result.result.value
fig.show()

And there you have it! You've successfully set up and run your first computational workflow on Covalent Cloud. We're thrilled to see where your computations take you next!

Full code
import covalent as ct
import covalent_cloud as cc
import numpy as np
import plotly.graph_objects as go
from scipy.interpolate import CubicSpline

# Save API key.
cc.save_api_key("YOUR_API_KEY")

# Define environments.
cc.create_env("numpy_env", pip=["numpy"], conda=["python=3.9", "pip"])
cc.create_env("interp_env", pip=["scipy", "plotly"], conda=["python=3.9", "pip"])

# Define executors.
low_compute = cc.CloudExecutor(env="numpy_env", num_cpus=1, memory=1024)
general_compute = cc.CloudExecutor(env="interp_env", num_cpus=4, memory=1024)


@ct.electron(executor=low_compute)
def rand_sin_func(x):
"""Generate sinusoid data with random harmonics."""
n_waves = np.random.randint(1, 10)
amps = 10 * np.random.rand(n_waves)
phis = 2 * np.pi * np.random.rand(n_waves)

y = 0.0
for i in range(n_waves):
y += amps[i] * np.sin((i + 1) * x + phis[i])
return y


@ct.electron(executor=general_compute)
def get_spline(x, y):
"""Get interpolation points between (x, y)"""
cs = CubicSpline(x, y)
new_x = np.linspace(x.min(), x.max(), 1000)
return np.asarray(cs(new_x))


@ct.electron(executor=general_compute)
def plot_interpolation(x, y, y_spline, fig=None, label_i=1):
"""Create a plot of the original and interpolated data"""
new_x = np.linspace(x.min(), x.max(), len(y_spline))
fig = fig or go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='markers', name=f'Original({label_i})'))
fig.add_trace(go.Scatter(x=new_x, y=y_spline, mode='lines', name=f'Interpolated({label_i})'))
fig.update_layout(
title="Random Sinusoid Interpolations",
xaxis_title="x",
yaxis_title="y"
)
return fig


@ct.lattice(executor=general_compute, workflow_executor=general_compute)
def workflow(num_curves):
"""Workflow that performs and plots several interpolations."""
x = np.linspace(0, 2 * np.pi)
fig = None
for i in range(num_curves):
y = rand_sin_func(x)
y_spline = get_spline(x, y)
fig = plot_interpolation(x, y, y_spline, fig=fig, label_i=i + 1)
return fig


if __name__ == "__main__":

# Dispatch workflow.
dispatch_id = cc.dispatch(workflow)(num_curves=4)

# Get result.
result = cc.get_result(dispatch_id, wait=True)

# Load result.
result.result.load()
fig = result.result.value
fig.show()

Just replace "YOUR_API_KEY" with your actual API key and you're good to go. Happy computing!