Phillip Weinberg
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Bloqade & Amazon Braket <center> <img src="https://hackmd.io/_uploads/rkpuzHZ4T.png" alt="Basic Model of rydberg driving" width="600"/> <br> In Aquila the qubits are encoded in a shell electron transition between its ground state and a highly excited state. This excitation is called a Rydberg excitation. </center> \ \ **Analog Hamiltonian Simulation (AHS)** has proven itself to be a powerful method of quantum computing -- one that's well-suited for solving optimization problems and performing computationally difficult simulations of other quantum systems. Unlike its counterpart digital/gate-based quantum computing, where you think of your programs in terms of unitary operations akin to classical gates, AHS switches things up where you program in terms of the **geometry of your qubits** (individual atoms!) and the waveforms of the lasers that are applied to them. With the laser control you can drive the atoms into excited states which allows them to interact and entangle via the Rydberg Blockade. <center> <img src="https://hackmd.io/_uploads/HkjeGHbVT.png", width="600"> <br> Visual represenation of an <b>Analog Hamiltonian Simulation</b> . Instead of using descrete gates the program is implemented via a continuous time evolution of a time dependent hamiltonian </center> \ \ We believe AHS is a useful step on the path universal to fault tolerant quantum computation, but one that requires **a different set of tools** than we're used to in gate-based QC. That's why we're psyched to announce the release of the **Bloqade for Python**! We got some super valuable feedback from the community and built that into a set of tools for programming AHS devices. We figure, hey, as the first ever provider of **publicly cloud-accessible neutral atom hardware** (available on Amazon Braket), we're in a great position to build tools that put the power of AHS hardware at your fingertips. ![image210](https://hackmd.io/_uploads/H1wlbLzNp.png) ## Cool Things You Can Do with Bloqade Some of Bloqade's main features (Smart Documentation, Parametrized Programs, and Integrated Visualization tools) have already been summarized in its [initial launch blog post](https://bloqade.quera.com/latest/blog/2023/posts/bloqade-release/). You can also find some great examples of Bloqade programs on its **[tutorials page](https://queracomputing.github.io/bloqade-python-examples/latest/) for inspiration**. Here we'll take the opportunity to highlight for you some of its other powerful features as well. ### A Prototypical Example Let's pair our neat features with a neat example: ```python! from bloqade import start, cast # Define the times for our waveform as variables we can assign values to later durations = cast(["ramp_time", "run_time", "ramp_time"]) rabi_oscillations_program = ( start.add_position((0,0)) .rydberg.rabi.amplitude.uniform.piecewise_linear( durations=durations, values=[0, "rabi_ampl", "rabi_ampl", 0] ) .detuning.uniform.constant(duration=sum(durations), value="detuning_value") ) ``` In this example we apply the right waveforms to get [Rabi oscillations](https://en.wikipedia.org/wiki/Rabi_cycle) from a single atom. We start by defining the **position** of our atom with `add_position` and then specifying the **Rabi frequency** (`.rabi`) and **Detuning** (`.detuning`) waveforms. You might notice the mix of strings and numbers, what's up with that? One of Bloqade's flagship features is that you can ***parametrize* your programs** by defining variables that can be assigned values later. The next section will dive into why exactly these are so neat to have. ### Parametrized Programs Many near-term applications for QC as well as AHS require some notion of parameterized programs. The key idea is that you either: * Want to explore how your program behaves across a **range of values** for a certain parameter (what happens if I put the atoms further/closer apart? What happens if I gradually increase the amplitude of a waveform?) * Want to figure out the **optimal values for your program** to achieve some objective (e.g. be able to try a new value on the fly and tweak that value based on prior results) To do the above, you need a program that has parameters you can tweak either during your program definition (the first point) or on the fly in a hybrid quantum-classical algorithm (our second point, and one which you'll see is quite easy to do with Amazon Braket Hybrid Jobs). Revisiting our original Rabi Oscillation program we can assign values like so: ```python import numpy as np program_with_assignments = ( rabi_oscillations_program.assign(ramp_time=0.06, run_time=3.0) .batch_assign(detuning_value=np.linspace(0, 10, 15)) .args(["rabi_ampl"]) ) ``` You can see there are three options for variable assignment: 1. You **assign a single value** to a single variable with `.assign()`. In this case we set our waveform ramp time to be 0.06 microseconds and the run time (where we hold the Rabi frequency constant) for 3.0 microseconds. 2. You **assign multiple values** to a single variable with `.batch_assign()`. 3. You **defer assignment until runtime** of a variable with `.args()`. This means that you wait until execution of your program to pass in a value versus statically defining it. The second option might seem a bit odd, but this is where Bloqade really shines: given multiple values for a single variable, Bloqade can **automatically generate multiple quantum tasks** that can either run on Amazon Braket or our eye-wateringly fast emulator you'll soon learn about. Furthermore, Bloqade **automatically handles compiling the results** for you so no more keeping track of individual task IDs or forgetting which task belongs to which parameter value. This is great for experimenting with different values and seeing how the behavior of your program changes (a "parameter sweep" in official parlance). The third option harkens back to the idea of **optimizing your program for a certain objective**. In the previously mentioned hybrid algorithm you have a quantum algorithm whose results are passed to a classical computer that, after some number crunching, tweaks the parameters of your quantum algorithm, working towards some optimal behavior. In this case we want to keep the same AHS program structure but just pass in our values later. But what's the benefit of all these variables and parameters if you don't have a place to test them all out? Fret not, Bloqade also has you covered on that front. ### Targeting Multiple Backends All Bloqade programs can be targeted to **multiple emulation and hardware backends** very easily using its dot-based chaining syntax. To select `braket` as your service simply select the `braket` attribute of your program. At this stage there will be two methods available for you, `aquila()` and `local_emulator()`. Each backend has different restrictions in terms of the types of AHS programs that can be run, e.g. emulators will have a lot more flexibility than what hardware will accept. Depending on the backend, there are also either one or two methods for executing your program. For **cloud devices**, Bloqade has an API for both **asynchronous** (`run_async()`) **and** **synchronous** (`run()`) method for executing the job. Local emulator backends only support the `run()` API. Now let's revisit the meaning of `args()` assignment. Every execution method has an `args()` argument, this is where you can **specify the values of the parameters** defined in `args()` when defining your program. The order of the arguments in the `args()` tuple is the order of the variables specified in the `args()` method. Continuing our Rabi Oscillation example program we can see all this come together nicely: ```python! results = program_with_assignments.braket.local_emulator().run(shots=100, args=(4,)) ``` Alternatively, you can also do the following: ```python! executable_program = program_with_assignments.braket.local_emulator() results = executable_program(4, shots=100) ``` Throughout this example we've relied on the Braket local emulator. However, Bloqade has another trick up its sleeve for emulation: its own blazing fast emulator! ### Built-In Bloqade Emulator While Bloqade.jl holds the crown in terms of performance, the Python version of the state vector simulator has been carefully optimized to **push the boundaries of what Python can do**. The emulator supports both two- and three-level atom configurations, along with global and local driving and support for the blockade subspace for our neutral atom experts. The blockade subspace and matrix calculations are **nearly optimal in both memory and time** -- we wrote them in pure NumPy and SciPy. We also have basic Numba JIT compiled sparse operations that further optimize memory when solving the time-dependent Schrödinger equation. We hope our Python emulator will allow you to explore a wide variety of applications for neutral atoms and prototype some neat new algorithms with AHS. ## Adaptive Jobs Remember those parameterized algorithms we mentioned earlier? Well it's now easier than ever to develop and execute those algorithms thanks to Braket Hybrid Jobs, where **all you need to do is add the `@hybrid_job` decorator** to your Python code. This submits the code to Amazon Braket which handles both which QPU to target as well as the classical resources with minimal additional code. Even better, you can combine the `@hybrid_job` decorator with Bloqade's parameterized programs to **develop hybrid algorithms for neutral atom hardware** faster than you can say "Neutral atom hybrid algorithms are awesome!" Okay maybe not that fast, but you'll be on your feet in no time! We'll prove this claim with an example where we want to find an optimal detuning waveform on top of a fixed Rabi frequency that solve the **Maximum Independent Set (MIS) problem** on our neutral atom quantum computer *Aquila*. MIS is a Combinatorial Optimization problem where given a graph you want to find the largest set of nodes such that no two nodes share an edge. MIS is NP-Hard and has a number of applications in scheduling and resource allocation. Additionally, **MIS a very natural problem for the AHS architecture** (check out this great [independent blog post](https://medium.com/the-modern-scientist/testing-maximal-independent-set-mis-with-queras-aquila-345ff32f26bf) about it!), as the Rydberg blockade effect causes the ground state of a collection of atoms within close enough proximity of each other to map to the problem on geometric graphs. The majority of the source code for this example as well as a detailed explanation can be [found here](https://github.com/QuEraComputing/QuEra-braket-examples/blob/main/HybridJob/hybrid-job.ipynb), but we want to highlight just how easy it is use `@hybrid_job` with a snippet from the example: ```python! from braket.jobs import ( InstanceConfig, hybrid_job, ) @hybrid_job( # select the quantum hardware your hybrid algorithm will target device = Devices.QuEra.Aquila, # Let Amazon Braket know what dependencies we need dependencies="requirements.txt", # select an Amazon EC2 instance for classical computation instance_config=InstanceConfig("ml.m5.large"), ) # accept a Bloqade program where the "args" method was used to declare that # a set of variables (in our case the parameterized detuning waveform) should have # on the fly assignment. def run_algo(assigned_program, n_calls=10, n_shots=10, detuning_bound=100): # Use scikit-optimize's bayesian optimization by gaussian processes function from skopt import gp_minimize # Keep track of Hybrid Job progress and cost with a custom cost function program_with_backend = assigned_program.braket.aquila() wrapped_cost_func = CostFuncWrapper(program_with_backend, shots=n_shots) # establish boundaries for the optimizer on how high/low a detuning value # each variable can take by first finding the number of parameters in # our program and then repeating the constraint that number of times n_params = len(program_with_backend.params.args_list) bounds = n_params * [(-detuning_bound, detuning_bound)] # The optimizer will call the cost function which in turn, # calls the actual program to execute on Aquila result = gp_minimize( wrapped_cost_func, bounds, callback=wrapped_cost_func.callback, n_calls=n_calls, ) # Associate with each detuning variable declared earlier a result from the optimizer, # so we can pass the values back to our AHS program detuning_values = { var.name: val for var, val in zip(detuning_vars, result.x) } return detuning_values ``` For the AHS program we've parameterized the detuning waveform so at each time step there is an associated variable which defines what values the detuning can take. This program is passed into a function `run_algo()` function with the `@hybrid_job` decorator. Note that in the decorator we specify **which quantum device to target** along with letting Amazon Braket know **which dependencies we need** and an Amazon EC2 instance. The actual thing that calls our program to run on *Aquila* is contained in a cost function instantiated by `CostFuncWrapper` that is later passed into scikit-optimize's `gp_minimize` function to help us **find the optimal detuning values** per each variable. The cost function we've defined also takes advantage of functionality from `braket.jobs` to log the progress of our program. Using the Bloqade Emulator with `@hybrid_job` (you can do this by setting the device ARN in the `@hybrid_job` decorator to `None` and changing the backend our AHS program uses to the Bloqade Python emulator) we obtain the following results after using the optimized detuning waveform on the Bloqade Emulator: ![](https://hackmd.io/_uploads/HyjpfOTzp.png) The leftmost panel shows the probabilities for each measurement while the center most panel shows what the actual geometric configuration looks like for a selected measurement. We've sleected the measurement with the highest probability and we see that its **geometric configuration is indeed the MIS of the graph** (the black nodes the atoms are in the Rydberg state and vice versa). The black nodes share no edges (first criteria for MIS) and it's the largest number of nodes possible that don't share an edge (second criteria for MIS). All in all, we like to think this nice pairing of Bloqade with `@hybrid_job` is one of those few instances in life where you can have your cake and eat it too.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully