Get started with Q# programs and Visual Studio Code

In this article you will find the steps to use VC Code to create and submit Q#, Jupyter Notebook, or Python quantum computing jobs to Azure Quantum using VS Code.

Submitting Q# jobs to Azure Quantum

Learn how to use VS Code to run, debug, and submit a Q# program to Azure Quantum.

Prerequisites

For installation details, see Installing the Modern QDK on VS Code.

Load a Q# sample program

  1. In VS Code, select File > New Text File and save the file as RandomNum.qs.
  2. Open RandomNum.qs and type sample, then select Random Bit sample from the list of options and save the file.

Note

You can also open your own Q# file. If you run an older Q# program and run into errors, see Testing and debugging or Migrating your programs to the Modern QDK.

Run a Q# program

  1. To test run your program locally on the built-in simulator, select Run Q# File from the play icon drop-down in the top-right, or press Ctrl+F5. Your output will appear in the debug console.
  2. To debug your program before submitting it to Azure Quantum, select Debug Q# file from the play icon, or press F5. Use the debugging controls at the top to step over, into, and out of the code. For more information about debugging Q# programs, see Testing and debugging.

Plot the frequency histogram

The frequency histogram represents the distribution of results obtained from running a quantum program multiple times, or "shots". Each bar in the histogram corresponds to a possible outcome, and its height represents the number of times that outcome is observed. The frequency histogram helps visualize the probability distribution of these outcomes.

  1. Select View -> Command Palette, or press Ctrl+Shift+P, and type “histogram” which should bring up the Q#: Run file and show histogram option. Select this option to open the Q# histogram window.

  2. Enter a number of shots to execute the program, for example, 100 shots, and press Enter. The histogram will display in the Q# histogram window.

  3. Click the top-left settings icon to display options.

    Screenshot the Q# histogram window in Visual Studio Code showing how to display settings.

  4. Click on a bar to display the percentage of that outcome. In this case there are two possible outcomes, 0 and 1, and the percentage of each outcome is close to 50%.

    Screenshot the Q# histogram window in Visual Studio Code.

Tip

You can zoom the histogram using the mouse scroll wheel or a trackpad gesture. When zoomed in, you can pan the chart by pressing 'Alt' while scrolling.

Connect to Azure Quantum and submit your job

Use the built-in Quantum Workspaces to connect and submit jobs directly from VS Code. For this example, you'll submit a job to the Rigetti simulator.

  1. In the Explorer pane, expand Quantum Workspaces.
  2. Select Add an existing workspace and follow the prompts to connect to your preferred directory, subscription, and workspace.
  3. Once you are connected, expand your workspace and expand the Rigetti provider.
  4. Select rigetti.sim.qvm as your target.
  5. Select the play icon to start submitting the current Q# program. If you get a popup, select Change the QIR target profile and continue.
  6. Add a name to identify the job.
  7. Add the number of shots, or number of times that the program is run.
  8. Press Enter to submit the job. The job status will display at the bottom of the screen.
  9. Expand Jobs and hover over your job, which displays the times and status of your job.
  10. To view the results, select the cloud icon next to the job name to download the results from your workspace storage and display it in VS Code.

Submitting Jupyter Notebooks jobs to Azure Quantum

Learn how to use VS Code to run, debug, and submit a Q# Jupyter Notebook to Azure Quantum. The steps in this article also apply to Jupyter Notebooks on your local Jupyter server or notebooks in the Azure Quantum portal.

Prerequisites

For installation details, see Installing the Modern QDK on VS Code.

Run and test your program in the local simulator

  1. In VS Code, select View > Command palette and select Create: New Jupyter Notebook.

  2. In the top-right, VS Code will detect and display the version of Python and the virtual Python environment that was selected for the notebook. If you have multiple Python environments, you may need to select a kernel using the kernel picker in the top right. If no environment was detected, see Jupyter Notebooks in VS Code for setup information.

  3. In the first cell of the notebook, run

    import qsharp
    import azure.quantum
    
    • The qsharp module activates the %%qsharp magic command that lets you enter Q# code directly into a cell.
    • The azure-quantum module provides connectivity to your Azure Quantum workspace.

    Note

    If the Jupyter Python kernel ipykernel is not detected, VS Code will prompt you to install it.

  4. Add another cell and enter this Q# code that returns a user-specified number of random bits:

    %%qsharp
    
    operation Random() : Result {
        use q = Qubit();
        H(q);
        let result = M(q);
        Reset(q);
        return result
    }
    
    operation RandomNBits(N: Int): Result[] {
        mutable results = [];
        for i in 0 .. N - 1 {
            let r = Random();
            set results += [r];
        }
        return results
    }
    
  5. To test your operation, you can use the eval method, which can call any Q# operation previously defined in the notebook:

    qsharp.eval("RandomNBits(4)")
    
    [Zero, One, One, Zero]
    
  6. To run your program to the local simulator, use the run method. Specify the shots, or number of times to run the program, and the simulator returns the results as a Python list.

    qsharp.run("RandomNBits(4)", shots=10)
    
    [[One, One, One, One],
    [Zero, Zero, One, Zero],
    [One, Zero, Zero, One],
    [Zero, One, Zero, Zero],
    [One, Zero, One, One],
    [One, Zero, One, Zero],
    [One, One, One, Zero],
    [One, One, One, One],
    [Zero, Zero, Zero, One],
    [One, Zero, Zero, One]]
    

Compile your job using the Base profile

When you run programs on the local quantum simulator, you can submit any type of Q# program. However, Azure Quantum hardware targets do not yet support the full capabilities required to run all Q# programs. In order to compile and submit Q# programs to Azure Quantum, you need to set your target profile to tell Q# which capabilities your target hardware supports. Currently, that is the Base profile. For more information, see Profile types in Azure Quantum.

To reinitialize the Q# interpreter and compile your program with the base profile:

  1. Use the init method to set the profile:

    qsharp.init(target_profile=qsharp.TargetProfile.Base)
    
  2. Since you reinitialized the interpreter, you need to run your code again with the new profile:

    %%qsharp
    
    operation Random() : Result {
        use q = Qubit();
        H(q);
        let result = M(q);
        Reset(q);
        return result
    }
    
    operation RandomNBits(N: Int): Result[] {
        mutable results = [];
        for i in 0 .. N - 1 {
            let r = Random();
            set results += [r];
        }
        return results
    }
    
  3. Next, use the compile method to specify the operation or function that is the entry point to your program. This compiles your code into QIR format, which can then be submitted to any quantum hardware:

    MyProgram = qsharp.compile("RandomNBits(4)")
    

Connect to Azure Quantum and submit your job

Now that you have your program compiled into the correct format, create an azure.quantum.Workspace object to connect to Azure Quantum. You'll use the Resource ID of your Azure Quantum workspace in order to connect. The Resource ID and location can be copied from your workspace overview page in the Azure portal.

  1. In a new cell, fill in your resource ID and location from your Azure Quantum workspace:

    MyWorkspace = azure.quantum.Workspace(
        resource_id = "MyResourceID",
        location = "MyLocation"
    )
    
  2. Use the get_targets method to see the available hardware targets in your workspace:

    MyTargets = MyWorkspace.get_targets()
    print("This workspace's targets:")
    MyTargets
    
  3. Select the rigetti.sim.qvm target:

    MyTarget = MyWorkspace.get_targets("rigetti.sim.qvm")
    
  4. Lastly, use the submit method to submit your program with its parameters and display the results:

    job = MyTarget.submit(MyProgram, "MyQuantumJob", shots=100)
    job.get_results()
    
    {'Histogram': ['[0, 0, 0, 0]',
      0.3,
      '[1, 0, 0, 0]',
      0.1,
      '[1, 1, 1, 1]',
      0.3,
      '[0, 1, 1, 1]',
      0.3]}
    
  5. All the properties of the job are accessible in job.details, for example:

    print(job.details)
    print("\nJob name:", job.details.name)
    print("Job status:", job.details.status)
    print("Job ID:", job.details.id)
    
    {'additional_properties': {'isCancelling': False}, 'id': '0150202e-9638-11ee-be2f-b16153380354', 'name': 'MyQuantumJob', 'provider_id': 'rigetti'...}
    Job name: MyQuantumJob
    Job status: Succeeded
    Job ID: 0150202e-9638-11ee-be2f-b16153380354
    

Submitting Python with Q# jobs to Azure Quantum

Learn how to use VS Code to write a Python program that calls Q# operations, connect to Azure using the Python commands or Azure CLI, and submit your job.

Prerequisites

For installation details, see Installing the Modern QDK on VS Code.

Create and import your Q# operations

With the qsharp package, you can store your functions and operations in Q# files and create Q# projects that let you call into any of them from your Python code. This especially helpful when you need to launch a program that takes input parameters.

  1. Follow the steps to create a Q# project.

  2. Open a new text file, add the following Q# code that returns a user-specified number of random bits, and save the file to your project as source.qs.

    Note

    Note that this Q# code doesn't have an @EntryPoint function like a Q# program (see Submitting Q# jobs to Azure Quantum), but it does require a namespace, unlike a Jupyter Notebook (see Submitting Jupyter Notebook jobs to Azure Quantum).

    namespace Sample {
    
      operation Random() : Result {
            use q = Qubit();
            H(q);
            let result = M(q);
            Reset(q);
            return result
      }
    
      operation RandomNBits(N: Int): Result[] {
            mutable results = [];
            for i in 0 .. N - 1 {
               let r = Random();
               set results += [r];
            }
            return results
      }
    }
    
  3. In the same folder, open another file and save it as randomNum.py.

  4. Add the following code to import the qsharp and azure.quantum modules.

    import qsharp
    import azure.quantum
    
  5. Next, add code to define the Q# project root folder and test run the target operation on the local simulator. The operation is called by <namespace>.<operation_name( )>, and in this case, you are passing in the number of random bits to return.

    qsharp.init(project_root = '/MyProjectRootFolder')
    print(qsharp.eval("Sample.RandomNBits(4)"))
    
    [Zero, One, One, Zero]
    
  6. You can also test the operation with the run method, which passes an additional shots parameter, and returns the results in a Python list. In randomNum.py, replace the previous print statement with the following:

    result = qsharp.run("Sample.RandomNBits(4)", shots=10)
    for x in result:
        print(x)
    
    [[One, One, One, One],
    [Zero, Zero, One, Zero],
    [One, Zero, Zero, One],
    [Zero, One, Zero, Zero],
    [One, Zero, One, One],
    [One, Zero, One, Zero],
    [One, One, One, Zero],
    [One, One, One, One],
    [Zero, Zero, Zero, One],
    [One, Zero, Zero, One]]
    

Compile your job using the Base profile

When you run programs on the local quantum simulator, you can submit any type of Q# program. However, Azure Quantum hardware targets do not yet support the full capabilities required to run all Q# programs. In order to compile and submit Q# programs to Azure Quantum, you need to set your target profile to tell Q# which capabilities that your target hardware supports. Currently, that is the Base profile. For more information, see Profile types in Azure Quantum.

Note

For Q# only programs in VS Code, VS Code sets the Base profile automatically.

  1. Use the init method to set the profile:

    qsharp.init(target_profile=qsharp.TargetProfile.Base)
    
  2. Then use the compile method to specify the operation or function that is the entry point to your program. The compiled program can then be submitted to any quantum hardware:

    MyProgram = qsharp.compile("Sample.RandomNBits(4)")
    

Connect to Azure Quantum and submit your job

You can connect to Azure Quantum and submit your job using a Python-created Workspace object, or connect and submit your job using Azure CLI. Using Azure CLI requires that you save the compiled program as a text file and submit that file using a CLI command.

Now that you have your program compiled into the correct format, create a azure.quantum.Workspace object to connect to Azure Quantum. You'll use the Resource ID of your Azure Quantum workspace in order to connect. The Resource ID and location can be copied from your workspace overview page in the Azure portal.

  1. Add the following code to randomNum.py, filling in your resource ID and location from your Azure Quantum workspace:

    workspace = azure.quantum.Workspace(
        resource_id = "MyResourceID",
        location = "MyLocation"
    )
    
  2. Use the get_targets method to display the available hardware targets in your workspace:

    MyTargets = workspace.get_targets()
    print("This workspace's targets:")
    for x in MyTargets:
        print(x)
    
  3. Select the rigetti.sim.qvm target:

    MyTarget = workspace.get_targets("rigetti.sim.qvm")
    
  4. Lastly, use the submit method to submit your program with its parameters. The job results are returned as a Python dictionary.

    job = MyTarget.submit(MyProgram, "MyPythonJob", shots=100)
    results = job.get_results()
    print("\nResults: ", results)
    
  5. To extract just the values and display them:

    resultList = results.get("Histogram")
    for x in resultList:
        print(x)
    
    [0, 0, 0, 0]
    0.3
    [1, 0, 0, 0]
    0.1
    [1, 1, 1, 1]
    0.3
    [0, 1, 1, 1]
    0.3
    
  6. All the properties of the job are accessible in job.details, for example:

    print(job.details)
    print("\nJob name:", job.details.name)
    print("Job status:", job.details.status)
    print("Job ID:", job.details.id)
    
    {'additional_properties': {'isCancelling': False}, 'id': '0fc396d2-97dd-11ee-9958-6ca1004ff31f', 'name': 'MyPythonJob', 'provider_id': 'rigetti'...}
    Job name: MyPythonJob
    Job status: Succeeded
    Job ID: fc396d2-97dd-11ee-9958-6ca1004ff31f
    

Next steps