Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating CLI extension for Azure Quantum #1879

Merged
merged 76 commits into from Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9ddc0e4
Azure quantum extension v0 (#2)
anpaz Jun 12, 2020
6663ec4
Fixing style issues
anpaz Jun 12, 2020
43c4bd7
Merge pull request #4 from anpaz-msft/quantum/master
anpaz Jun 12, 2020
739e015
Merge branch 'master' into master
anpaz Jun 12, 2020
75410f3
Incorporating feedback (#6)
anpaz Jun 17, 2020
000e8c4
Help
anpaz Jun 18, 2020
a5eb2e1
Make storage account optional (#7)
anpaz Jun 20, 2020
d389d1e
Storage is now optional (#8)
anpaz Jun 26, 2020
aa8a4b2
Making storage an argument, not an env variable (#9)
anpaz Jun 26, 2020
91e8e99
Adding implementation of 'az quantum workspace delete' command.
ricardo-espinoza Oct 19, 2020
1d3f7f8
Setting new temporary version.
ricardo-espinoza Oct 19, 2020
cdd3c07
Fixing missing file in test change
ricardo-espinoza Oct 19, 2020
b6c5cf6
Adding details to README.md (#5)
anpaz Oct 20, 2020
e5b5aa4
Updating generated files for Azure Quantum resource manager from new …
ricardo-espinoza Oct 20, 2020
d092bb3
Remove manual edit of generated file.
ricardo-espinoza Oct 20, 2020
8446cd8
Merge pull request #11 from anpaz/ricardoe/quantum/update-swagger-files
ricardo-espinoza Oct 20, 2020
485a152
Merge pull request #10 from anpaz/ricardoe/workspaces/delete
ricardo-espinoza Oct 20, 2020
ff55bea
Updating generated files for Azure Quantum data plane from new swagge…
ricardo-espinoza Oct 21, 2020
41d8837
Merge pull request #12 from anpaz/ricardoe/quantum/update-swagger-fil…
ricardo-espinoza Oct 21, 2020
14909d0
Updating generated files for Azure Quantum resource manager from new …
ricardo-espinoza Nov 7, 2020
dd5d5d1
Adding implementation of 'az quantum workspace create' command. (#14)
ricardo-espinoza Nov 12, 2020
912ce6f
Update Azure CLI quantum extension to multi-region (#17)
ricardo-espinoza Dec 8, 2020
0b230ee
Updating swagger files per commit 44563991425d862ba4e8090a2b5b6caf833…
ricardo-espinoza Dec 8, 2020
6445133
Fixing tests for multi-region URL change on Az CLI quantum extension …
ricardo-espinoza Dec 10, 2020
6325cb0
Incorporating ARM feedback (#18)
anpaz Dec 15, 2020
189b388
run command
anpaz Dec 28, 2020
e334f5c
Setting default location in workspace calls if not specified (#20)
ricardo-espinoza Jan 4, 2021
4b2d993
updating python azure quantum rest client (#21)
anpaz Jan 8, 2021
3cd44d9
Update generated files from swagger file (Version 2021-01-11) (#22)
ricardo-espinoza Jan 15, 2021
097e3d0
Hot fixes on December 2020 release of Azure CLI extension (#23)
ricardo-espinoza Jan 15, 2021
ac57090
Update CLI with generated clients from more recent swagger files (#24)
ricardo-espinoza Jan 17, 2021
184f269
Update src/quantum/README.rst
ricardo-espinoza Jan 18, 2021
6166a86
Update src/quantum/README.rst
ricardo-espinoza Jan 18, 2021
9d3cd76
Update src/quantum/README.rst
ricardo-espinoza Jan 18, 2021
2d8813b
Update src/quantum/README.rst
ricardo-espinoza Jan 18, 2021
172e848
Require location as a mandatory parameter in workspace specification …
ricardo-espinoza Jan 19, 2021
17b5ff2
Merge pull request #26 from Azure/master
ricardo-espinoza Jan 22, 2021
4b13bb6
Resetting the version history for the released version.
ricardo-espinoza Jan 25, 2021
f5ee1c0
Fix description of workspace clear command
ricardo-espinoza Jan 25, 2021
2113afa
Merge pull request #27 from anpaz/ricardoe/cr/2021-01-25
ricardo-espinoza Jan 25, 2021
0be66ff
Updatig Readme file to RST format.
ricardo-espinoza Jan 25, 2021
ddc6450
Update Readme file per pull request comments.
ricardo-espinoza Jan 25, 2021
efcd2dd
Fixing az quantum run and execute commands to include location parameter
ricardo-espinoza Jan 25, 2021
a8b84d5
Merge pull request #28 from anpaz/ricardoe/bugfix/24509
ricardo-espinoza Jan 25, 2021
5ae53c4
Performing role assignment on storage account on workspace creation. …
ricardo-espinoza Jan 27, 2021
b4879b5
Add warning message about providers during workspace creation (#30)
ricardo-espinoza Jan 27, 2021
407a80c
Enable command az quantum workspace quotas (#31)
ricardo-espinoza Jan 28, 2021
2b8da4d
Removing extra space in Readme.rst
ricardo-espinoza Jan 28, 2021
150e7e6
Fix punctuation in Readme.rst
ricardo-espinoza Jan 28, 2021
d0aaa9e
Update src/quantum/README.rst
ricardo-espinoza Jan 28, 2021
815a6f9
Update src/quantum/azext_quantum/_params.py
ricardo-espinoza Jan 28, 2021
ccadf4a
First round of code review feedback on Readme.rst
ricardo-espinoza Jan 28, 2021
eae418f
Improve code readability on job commands
ricardo-espinoza Jan 28, 2021
0b05b48
Avoid IndexError in case of malformed URL
ricardo-espinoza Jan 28, 2021
f596766
Extended info on targetId parameter
ricardo-espinoza Jan 28, 2021
b0bafff
Add help to each individual command
ricardo-espinoza Jan 28, 2021
8e83036
Reorganize sections in Readme.rst and merge in a single set of instru…
ricardo-espinoza Jan 28, 2021
e3775db
Merge pull request #32 from anpaz/ricardoe/cr/2021-01-28
ricardo-espinoza Jan 28, 2021
ffa92d6
Static analysis fixes
ricardo-espinoza Jan 29, 2021
42ee982
Fix CLI Linter errors
ricardo-espinoza Jan 29, 2021
2e47a48
Fix CLI Linter errors. Part 2
ricardo-espinoza Jan 29, 2021
dca48d8
Fix typo in show command.
ricardo-espinoza Jan 29, 2021
a34aa0f
Fix show command for Linter
ricardo-espinoza Jan 29, 2021
70e095c
Use standard name for show command method
ricardo-espinoza Jan 29, 2021
55cabc5
Modify workspace create test to skip role assignment
ricardo-espinoza Jan 29, 2021
fdfae06
Update tests with workspace names used currently.
ricardo-espinoza Jan 29, 2021
76c53fd
Update test recordings.
ricardo-espinoza Jan 29, 2021
b6da8f1
Set subscription for the recordings.
ricardo-espinoza Jan 29, 2021
91e7224
Update test recordings.
ricardo-espinoza Jan 29, 2021
350d952
Update QDK version number
ricardo-espinoza Jan 29, 2021
931a28c
Remove asserts and checks for subscription
ricardo-espinoza Jan 29, 2021
dd71ef3
Experiment: Remove check for preview subscription
ricardo-espinoza Jan 29, 2021
090c3fe
Refresh recordings with current test values.
ricardo-espinoza Jan 29, 2021
cd42ead
Update recordings after typo fix.
ricardo-espinoza Jan 29, 2021
46a61c2
Remove commented out API that references subscription
ricardo-espinoza Jan 29, 2021
847fd48
Enable QuantumJobsScenarioTest.test_submit_args only on live mode
ricardo-espinoza Jan 29, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -116,6 +116,8 @@

/src/account/ @zikalino

/src/quantum/ @anpaz-msft

/src/datashare/ @fengzhou-msft

/src/k8sconfiguration/ @NarayanThiru
Expand Down
9 changes: 9 additions & 0 deletions src/quantum/HISTORY.rst
@@ -0,0 +1,9 @@
.. :changelog:

Release History
===============

0.11.2906.2
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
++++++
* Initial release. Version intended to work with Azure Quantum Private Preview
and with QDK version 0.11.2906.*
161 changes: 161 additions & 0 deletions src/quantum/README.rst
@@ -0,0 +1,161 @@
Microsoft Azure CLI 'quantum' Extension
anpaz marked this conversation as resolved.
Show resolved Hide resolved
==========================================

Azure Quantum is the first open Quantum computing platform. It offers a range of services
from quantum hardware to full-state simulators and quantum inspired optimizations,
providing developers and customers access to the most competitive quantum offering
on the market.

To learn more about azure quantum visit:
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
https://azure.microsoft.com/en-us/services/quantum/

To learn more about quantum computing and Microsoft's Quantum Development Kit visit:
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
https://docs.microsoft.com/quantum/


# Using the `az quantum` extension to list and manage jobs in Azure Quantum

1. Log in to Azure using your credentials.
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
```dotnetcli
az login
```
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
>[!NOTE] In case you have more than one subscription associated with your Azure account you must specify the
>subscription you want to use. You can do this with the command `az account set -s <Your subscription ID>`.

2. You can see all the Azure Quantum workspaces in your subscription with the `az quantum workspace list` command:
```dotnetcli
az quantum workspace list
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
```

3. You can use `quantum workspace set` to select a default workspace you want to use
to list and submit jobs. Note that you also need to specify the resource group.
```dotnetcli
az quantum workspace set -g MyResourceGroup -w MyWorkspace -o table
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved

Location Name ResourceGroup
----------- --------------------------------- --------------------------------
westus ws-yyyyyy rg-yyyyyyyyy
```

4. You can check the current default workspace with the command `az quantum workspace show`.
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved

```dotnetcli
az quantum workspace show -o table

Location Name ResourceGroup
----------- --------------------------------- --------------------------------
westus ws-yyyyyy rg-yyyyyyyyy
```

5. You can see all the jobs submitted a workspace using `az quantum job list`.
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved

```dotnetcli
az quantum job list -o table

Id State Target Submission time
------------------------------------ ------- -------------- ---------------------------------
yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Waiting MyProvider.MyTarget 2020-06-12T14:20:18.6109317+00:00
```
The console will output the information about the job, including the ID of the job.

6. You can use the ID of the job to track its status:
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
```dotnetcli
az quantum job show -id yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy -o table

Id State Target Submission time
------------------------------------ ------- -------------- ---------------------------------
yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Waiting MyProvider.MyTarget 2020-06-12T14:20:18.6109317+00:00
```

7. Once the job finishes you can visualize the job's results with `az quantum job output`:
```dotnetcli
az quantum job output -id yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy -o table

Result Frequency
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
-------- ----------- -------------------------
[0,0] 0.25000000 ▐█████ |
[1,0] 0.25000000 ▐█████ |
[0,1] 0.25000000 ▐█████ |
[1,1] 0.25000000 ▐█████ |
```



# Submitting Q# programs for execution from the command line

## Prerequisites

- You need to have an Azure Quantum workspace in your subscription.
- Install the [Quantum Development Kit](https://docs.microsoft.com/quantum/install-guide/standalone), if you haven't already.


## Write your quantum application

First you need to have the Q# quantum application that you want to execute in
Azure Quantum.

>[!TIP] If this is the first time for you to create Q# quantum applications, you can learn
>how in our [Microsoft Learn
>module](https://docs.microsoft.com/en-us/learn/modules/qsharp-create-first-quantum-development-kit/).
>

In this case we will use a simple quantum random bit generator. We create a Q#
project and substitute the content of `Program.qs` with the following code:

```qsharp
namespace RandomBit {

open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;

@EntryPoint()
operation GenerateRandomBit() : Result {
using (q = Qubit()) {
H(q);
return MResetZ(q);
}
}
}
```
Note that the `@EntryPoint` attribute tells Q# which operation to run when the program starts.

### Submit the job

In this example we are going to use IonQ as the provider and the
`ionq.simulator` as target. To submit the job to the currently selected
default quantum workspace `az quantum job submit`:
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved

```
az quantum job submit --target-id ionq.simulator --job-name Hello -o table

Name Id Status Target Submission time
----- ------------------------------------ -------- -------------- ---------------------------------
Hello yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Waiting ionq.simulator 2020-06-17T17:07:07.3484901+00:00

```

Once the job completes (i.e. it's in a **Successful** state), use `az quantum job output` to see the results:
```
az quantum job output -id yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy -o table

Result Frequency
-------- ----------- -------------------------
[0,0] 0.25000000 ▐█████ |
[0,1] 0.75000000 ▐████████████████ |
```
The output shows a histogram with the frequency a specific results was measured. In the example above
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
the result `[0,1]` was observed 75% of the times.


Finally, you can use `az quantum execute` as a shortcut for both, submitting and getting the results of execution.
```
az quantum execute --target-id ionq.simulator --job-name Hello2 -o table
.....
Result Frequency
-------- ----------- -------------------------
[0,0] 0.25000000 ▐█████ |
[0,1] 0.75000000 ▐████████████████ |
```


26 changes: 26 additions & 0 deletions src/quantum/azext_quantum/__init__.py
@@ -0,0 +1,26 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader

import azext_quantum._help # pylint: disable=unused-import


class QuantumCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
super(QuantumCommandsLoader, self).__init__(cli_ctx=cli_ctx)

def load_command_table(self, args):
from azext_quantum.commands import load_command_table
load_command_table(self, args)
return self.command_table

def load_arguments(self, command):
from azext_quantum._params import load_arguments
load_arguments(self, command)


COMMAND_LOADER_CLS = QuantumCommandsLoader
51 changes: 51 additions & 0 deletions src/quantum/azext_quantum/_client_factory.py
@@ -0,0 +1,51 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

# pylint: disable=line-too-long

import os


def is_env(name):
return 'AZURE_QUANTUM_ENV' in os.environ and os.environ['AZURE_QUANTUM_ENV'] == name


def base_url():
if 'AZURE_QUANTUM_BASEURL' in os.environ:
return os.environ['AZURE_QUANTUM_BASEURL']
if is_env('canary'):
return "https://app-jobs-canarysouthcentralus.azurewebsites.net/"
return "https://app-jobscheduler-prod.azurewebsites.net/"
anpaz marked this conversation as resolved.
Show resolved Hide resolved


def _get_data_credentials(cli_ctx, subscription_id=None):
from azure.cli.core._profile import Profile
profile = Profile(cli_ctx=cli_ctx)
creds, _, _ = profile.get_login_credentials(subscription_id=subscription_id, resource="https://quantum.microsoft.com")
anpaz marked this conversation as resolved.
Show resolved Hide resolved
return creds


def cf_quantum(cli_ctx, subscription_id=None, resource_group_name=None, workspace_name=None):
from .vendored_sdks.azure_quantum import QuantumClient
creds = _get_data_credentials(cli_ctx, subscription_id)
return QuantumClient(creds, subscription_id, resource_group_name, workspace_name, base_url=base_url())


def cf_quantum_mgmt(cli_ctx, *_):
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from .vendored_sdks.azure_mgmt_quantum import QuantumManagementClient
return get_mgmt_service_client(cli_ctx, QuantumManagementClient)


def cf_workspaces(cli_ctx, *_):
return cf_quantum_mgmt(cli_ctx).workspaces


def cf_providers(cli_ctx, subscription_id=None, resource_group_name=None, workspace_name=None):
return cf_quantum(cli_ctx, subscription_id, resource_group_name, workspace_name).providers


def cf_jobs(cli_ctx, subscription_id=None, resource_group_name=None, workspace_name=None):
return cf_quantum(cli_ctx, subscription_id, resource_group_name, workspace_name).jobs
63 changes: 63 additions & 0 deletions src/quantum/azext_quantum/_help.py
@@ -0,0 +1,63 @@
# coding=utf-8
ricardo-espinoza marked this conversation as resolved.
Show resolved Hide resolved
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from knack.help_files import helps # pylint: disable=unused-import

helps['quantum'] = """
type: group
short-summary: Manage Azure Quantum Workspaces and submit jobs to Azure Quantum Providers.
anpaz marked this conversation as resolved.
Show resolved Hide resolved
"""

helps['quantum job'] = """
type: group
short-summary: Manage jobs for Azure Quantum.
examples:
- name: Get the list of jobs from an Azure Quantum workspace
text: |-
az quantum job list -g MyResourceGroup -w MyWorkspace
- name: Submit the Q# program from the current folder
text: |-
az quantum job submit -g MyResourceGroup -w MyWorkspace \\
--job-name MyJob
- name: Get the status of an Azure Quantum job
text: |-
az quantum job show -g MyResourceGroup -w MyWorkspace \\
-id yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy --query status
- name: Print the results of a successful Azure Quantum job
text: |-
az quantum job output -g MyResourceGroup -w MyWorkspace \\
-id yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy -o table
"""

helps['quantum target'] = """
type: group
short-summary: Manage execution targets for Azure Quantum workspaces.
examples:
- name: Get the list of targets available in a Azure Quantum workspaces
text: |-
az quantum target list -g MyResourceGroup -w MyWorkspace
- name: Select a default when submitting jobs to Azure Quantum
text: |-
az quantum target set -t target-id
- name: Show the currently selected default target
text: |-
az quantum target show
"""

helps['quantum workspace'] = """
type: group
short-summary: Manage Azure Quantum workspaces.
examples:
- name: Get the list of Azure Quantum workspaces available
text: |-
az quantum workspace list
- name: Select a default Azure Quantum workspace for future commands
text: |-
az quantum workspace set -g MyResourceGroup -w MyWorkspace
- name: Show the currently selected default Azure Quantum workspace
text: |-
az quantum workspace show
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Azure CLI's convention, we create help entry for each command group and command. We put examples in command's help. For example,

helps['quantum workspace create']

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for the suggestion.

45 changes: 45 additions & 0 deletions src/quantum/azext_quantum/_params.py
@@ -0,0 +1,45 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long

from knack.arguments import CLIArgumentType


def load_arguments(self, _):
workspace_name_type = CLIArgumentType(options_list=['--workspace-name', '-w'], help='Name of the Quantum Workspace. You can configure the default workspace using `az quantum workspace set`.', id_part=None, required=False)
program_args_type = CLIArgumentType(nargs='*', help='List of arguments expected by the Q# operation specified as --name=value after `--`.')
target_id_type = CLIArgumentType(options_list=['--target-id', '-t'], help='Target id.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

help='Target id.' is simple. It just repeats parameter name "target id".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explanation expanded.

project_type = CLIArgumentType(help='The location of the Q# project to submit. Defaults to current folder.')
job_name_type = CLIArgumentType(help='A friendly name to give to this execution of the program.')
shots_type = CLIArgumentType(help='The number of times to execute the Q# program on the given target.')
no_build_type = CLIArgumentType(help='If specified, the Q# program is not built before submitting.')

with self.argument_context('quantum workspace') as c:
c.argument('workspace_name', workspace_name_type)

with self.argument_context('quantum target') as c:
c.argument('workspace_name', workspace_name_type)
c.argument('target_id', options_list=['--target-id', '-t'], help='Target id.')

with self.argument_context('quantum job') as c:
c.argument('workspace_name', workspace_name_type)
c.argument('job_id', options_list=['--job-id', '-id'], help='Job id.')
c.argument('target_id', target_id_type)
c.argument('project', project_type)
c.argument('job_name', job_name_type)
c.argument('shots', shots_type)
c.argument('no_build', no_build_type)

with self.argument_context('quantum job submit') as c:
c.positional('program_args', program_args_type)

with self.argument_context('quantum execute') as c:
c.argument('workspace_name', workspace_name_type)
c.argument('target_id', target_id_type)
c.argument('project', project_type)
c.argument('job_name', job_name_type)
c.argument('shots', shots_type)
c.argument('no_build', no_build_type)
c.positional('program_args', program_args_type)