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 3.11 (installation) and are familiar with setting up and using virtual environments.

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

Usage​

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
from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.error_mitigation import Debias

device = AwsDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")
circuit = Circuit().h(0).cnot(0, 1)

task = device.run(circuit, shots=2500, device_parameters={"errorMitigation": Debias()})

result = task.result()
print(result.measurement_counts)

Here's the same example using the Strangeworks SDK (assuming you have already authenticated). Notice the difference in the device_parameters argument:

Strangeworks Braket Service: Error Mitigation
from strangeworks_braket import StrangeworksDevice
from braket.circuits import Circuit

device = StrangeworksDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")
circuit = Circuit().h(0).cnot(0, 1)

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

result = task.result()
print(result.measurement_counts)

πŸ₯³ 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​

Hybrid jobs allow for the integration of classical and quantum computing tasks. The execution of these tasks on the Strangeworks Platform is similar to Braket Hybrid Jobs with a few minor differences.

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()

To run the examples, first save the below script as braket_hybrid_script.py or download it here: braket_hybrid_script.py

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

Amazon Braket Hybrid Jobs​

Here's an example of running a simple hybrid job using Amazon Braket. For more information see Hybrid Jobs:

Amazon Braket: Hybrid Jobs
from braket.aws import AwsQuantumJob
from braket.devices import Devices

# Initialize the quantum device
device = AwsDevice("arn:aws:braket:::device/quantum-simulator/amazon/sv1")

# Submit the hybrid job
job = AwsQuantumJob.create(
device,
source_module="braket_hybrid_script.py",
entry_point="braket_hybrid_script.py:main",
hyperparameters={"shots": 100, "num_iter": 5}
)

print(f"πŸ”„ Job {job.id} submitted!")
result = job.result()
print(result)

Strangeworks Braket Hybrid Jobs​

Here’s how the same task is implemented using the Strangeworks SDK.

The key differences between Strangeworks and Braket for job submission are:

  • In Braket, the job creation process involves using the AwsQuantumJob.create() function and explicitly specifying parameters such as the device, source module, entry point, and hyperparameters.

  • In Strangeworks, the run_hybrid() method is used for job submission, with the source module path and hyperparameters passed directly as arguments.

These differences highlight how Strangeworks aims to streamline the job submission process and make it more accessible for users:

Strangeworks Braket Service: Hybrid Jobs
import strangeworks
from strangeworks_braket import StrangeworksDevice

# Authenticate with your Strangeworks API key
strangeworks.authenticate(api_key="your-api-key")

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

# Submit the hybrid job
soure_module = "./braket_hybrid_script.py"
hyperparameters = {"shots": 100, "num_iter": 5}
sw_job = device.run_hybrid(soure_module, hyperparameters)

# Retrieve the job result
result = sw_job.result()
print(result)

πŸ₯³ Success! You may view your job in the portal.

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

Unsupported Providers​

Qiskit​

The Qiskit Braket Provider is not currently supported by the Strangeworks Platform. If you would like to use Qiskit with Strangeworks please refer to the strangeworks-qiskit and strangeworks-qiskit-runtime packages.

Pennylane​

Pennylane is not currently supported by the Strangeworks Platform. If you would like to use Pennylane with Amazon Braket, please refer to the Pennylane documentation.

Pulse​

Braket Pulse is not currently supported by the Strangeworks Platform. If you would like to use Braket Pulse with Amazon Braket, please refer to the Braket Pulse documentation.