Skip to main content

Strangeworks-Braket

PyPI version

The strangeworks-braket package provides a similar experience to Amazon Braket.

šŸ“‘ Package Documentation

Installationā€‹

To get started, make sure you have Python 3.10 or above (installation) and are familiar with setting up and using virtual environments.

pip install -U pip && pip install strangeworks-braket

Usageā€‹

Here's a simple example of creating a Bell state with Amazon Braket.

Before running:

  1. Set up your environment and install strangeworks-braket
  2. In the portal, Activate Amazon Braket to create a Resource
  3. Replace your-api-key with your key from the Portal homepage
  4. Run the script!
Amazon Braket: Hello World
import strangeworks
from braket.circuits import Circuit
from strangeworks_braket import StrangeworksDevice

# get your API key from the Strangeworks Portal
strangeworks.authenticate(
api_key="your-api-key",
)

# Optional: If you have multiple instances (resources) of a product,
# you can set the resource to use here.
# strangeworks.set_resource_for_product('your-resource-slug', 'amazon-braket')


# Optional: You can list the Braket devices available on
# the Strangeworks Platform
devices = StrangeworksDevice.get_devices(statuses=["ONLINE"])
print("Available devices:")
for device in devices:
print(f" - {device.name} ({device.arn})")

# create a simple quantum circuit
bell_state = Circuit().h(0).cnot(0, 1)

# Choose a device (an AWS-hosted simulator in this case)
tn1 = StrangeworksDevice("arn:aws:braket:::device/quantum-simulator/amazon/sv1")

# Execute the circuit
print("\nšŸ¤– Executing Circuit...\n")

task = tn1.run(bell_state, 1000)

# At this point, the job is running on the Strangeworks Platform.
# You can check the status of the job in the Portal, even if
# stop this script.
print(f"ā³ Job {task.id} submitted!\n")

# Lots of good info in here
result = task.result()

# View the counts (also visible in the Portal in a chart šŸ“Š)
print(f"šŸŽ‰ šŸ“Š Counts: {result.measurement_counts}\n")

šŸ„³ Success! You may view your job in the portal.

šŸ˜… Something went wrong? Find us in Slack!

Using IonQ's Error Mitigationā€‹

Amazon Braket: Error Mitigation
import strangeworks
from braket.circuits import Circuit
from strangeworks_braket import StrangeworksDevice

# get your API key from the Strangeworks Portal
strangeworks.authenticate(
api_key="your-api-key",
)

# create a simple quantum circuit
bell_state = Circuit().h(0).cnot(0, 1)

# Choose a device (an AWS-hosted simulator in this case)
dev = StrangeworksDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")

# Execute the circuit
print("\nšŸ¤– Executing Circuit...\n")

task = dev.run(
bell_state,
shots=2500,
device_parameters={
"errorMitigation": [
{"type": "braket.device_schema.error_mitigation.debias.Debias"}
]
},
)

# At this point, the job is running on the Strangeworks Platform.
# You can check the status of the job in the Portal, even if
# stop this script.
print(f"ā³ Job {task.id} submitted!\n")

# Lots of good info in here
result = task.result()

# View the counts (also visible in the Portal in a chart šŸ“Š)
print(f"šŸŽ‰ šŸ“Š Counts: {result.measurement_counts}\n")

šŸ„³ Success! You may view your job in the portal.

šŸ˜… Something went wrong? Find us in Slack!

Quera-Aquilaā€‹

Here's a simple example of creating a analogue Hamiltonian simulation to run on Aquila* with Amazon Braket. *Availability.

Before running:

  1. Set up your environment and install strangeworks-braket
  2. In the portal, Activate Amazon Braket to create a Resource
  3. Replace your-api-key with your key from the Portal homepage
  4. Run the script!
Amazon Braket: Aquila
import strangeworks
from strangeworks_braket import StrangeworksDevice
from braket.timings.time_series import TimeSeries
from braket.ahs.driving_field import DrivingField
import numpy as np
from strangeworks_braket.utils.ahs_utils import rabi_pulse, constant_time_series
from braket.ahs.atom_arrangement import AtomArrangement
from braket.ahs.hamiltonian import Hamiltonian
from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation

# get your API key from the Strangeworks Portal
strangeworks.authenticate(
api_key="your-api-key",
)

# Optional: If you have multiple instances (resources) of a product,
# you can set the resource to use here.
# strangeworks.set_resource_for_product('your-resource-slug', 'amazon-braket')

# Initialize Device
device = StrangeworksDevice("arn:aws:braket:us-east-1::device/qpu/quera/Aquila")

# Create Driving Parameters

rydberg = device.properties.paradigm.rydberg
omega_const = 1.5e7 # rad / s
rabi_pulse_area = np.pi/np.sqrt(3) # rad
omega_slew_rate_max = float(rydberg.rydbergGlobal.rabiFrequencySlewRateMax) # rad/s^2

time_points, amplitude_values = rabi_pulse(rabi_pulse_area, omega_const, 0.2 * omega_slew_rate_max)

amplitude = TimeSeries()
for t, v in zip(time_points, amplitude_values):
amplitude.put(t, v)

detuning = constant_time_series(amplitude, 0.0)
phase = constant_time_series(amplitude, 0.0)


drive = DrivingField(
amplitude=amplitude,
detuning=detuning,
phase=phase
)


# Create Register
separation = 5e-6
block_separation = 15e-6
k_max = 5
m_max = 5

register = AtomArrangement()
for k in range(k_max):
for m in range(m_max):
register.add((block_separation*m, block_separation*k + separation/np.sqrt(3)))
register.add((block_separation*m-separation/2, block_separation*k - separation/(2*np.sqrt(3))))
register.add((block_separation*m+separation/2, block_separation*k - separation/(2*np.sqrt(3))))

# Combine to create Analogue Hamiltonian

ahs_program = AnalogHamiltonianSimulation(
register=register,
hamiltonian=drive
)
discrete_program = ahs_program.discretize(device)

# Execute the circuit
print("\nšŸ¤– Executing Circuit...\n")

n_shots = 100
task = device.run(discrete_program, n_shots)

# At this point, the job is running on the Strangeworks Platform.
# You can check the status of the job in the Portal, even if
# stop this script.
print(f"ā³ Job {task.id} submitted!\n")

# Lots of good info in here
result = task.result()

šŸ„³ Success! You may view your job in the portal.

šŸ˜… Something went wrong? Find us in Slack!

Hybrid Jobsā€‹

Here's a simple example of custom submiting user defined scripts to devices on Amazon Braket. For more details and trouble shooting, see https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html

An example script is shown below which will run a simple bell state circuit a number of times given by the input parameter num_iter.

The form of the script has to follow a number of guidelines:

  • The script must contain a function called main that takes no inputs, def main(). The inputs will be read in by the load_hyperparameters(), see example below. This will be the entry point for the aws job.
  • The script must contain only one function called main
  • The braket tracker must be imported, from braket.tracking import Tracker
  • The braket tracker must be started on the line right after def main(): or immediately following any comments after def main():
  • The braket save job result function must be imported from braket.jobs import save_job_result
  • The results of the tracker must saved using the save_job_result function from braket by including "task summary": t.quantum_tasks_statistics(), in the output dictionary.
  • Nothing can follow save_job_result in the function main()
Amazon Braket: Hybrid Job Script

import json
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.jobs import save_job_result
from braket.tracking import Tracker


def main():
"""
Example Hybrid Job File
"""
t = Tracker().start()

device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"]
# Initialise device
device = AwsDevice(device_arn)
print(f"Using device {device}")

hyperparams = load_hyperparameters()
print("Hyperparameters are:", hyperparams)

shots = int(hyperparams.get("shots"))
num_iter = int(hyperparams.get("num_iter"))

counts = []
bell = Circuit().h(0).cnot(0, 1)
for count in range(num_iter):
task = device.run(bell, shots=shots)
print(task.result().measurement_counts)
counts.append(task.result().measurement_counts)

# return results as strings
save_job_result(
{
"counts": json.dumps(counts),
"task summary": t.quantum_tasks_statistics(),
"estimated cost": t.qpu_tasks_cost() + t.simulator_tasks_cost()
}
)


def load_hyperparameters():
"""Load the Hybrid Job hyperparameters"""
hp_file = os.environ["AMZN_BRAKET_HP_FILE"]
with open(hp_file) as f:
hyperparams = json.load(f)
return hyperparams

To run this example save the above script as braket_hybrid_script.py or download it here: braket_hybrid_script.py Then in a new python file or notebook use the following to submit the job, replacing your-api-key:

Amazon Braket: Hybrid Jobs
import strangeworks
from strangeworks_braket import StrangeworksDevice

# get your API key from the Strangeworks Portal
strangeworks.authenticate(
api_key="your-api-key",
)

# Optional: If you have multiple instances (resources) of a product,
# you can set the resource to use here.
# strangeworks.set_resource_for_product('your-resource-slug', 'amazon-braket')

# Initialize Device
# Try on simulator
device = StrangeworksDevice("arn:aws:braket:::device/quantum-simulator/amazon/sv1")

# Path to user defined file
filepath = "./braket_hybrid_script.py"

# Inputs for user defined file
hyperparameters = {"shots": 100, "num_iter": 5, "nqubits": 2}

# Submit job
sw_job = device.run_hybrid(filepath, hyperparameters)

# At this point, the job is running on the Strangeworks Platform.
# You can check the status of the job in the Portal, even if
# stop this script.
print(f"ā³ Job {sw_job.id} submitted!\n")

# Lots of good info in here
result = sw_job.result()

šŸ„³ Success! You may view your job in the portal.

šŸ˜… Something went wrong? Find us in Slack!