From 9e776d9de8a7c01c4af5d8b75098d7ed437f6f68 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 30 Aug 2022 11:40:36 -0700 Subject: [PATCH 01/65] Temporarily append build number to version number --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index 193ee93b80d..8ec975da18a 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.16.0" +CLI_REPORTED_VERSION = "0.16.0.4" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 3c26d228bd9..13fa4989491 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.16.0' +VERSION = '0.16.0.4' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From 81c1e53d5f73d41bc342c3c5d053b486c6338169 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 2 Sep 2022 14:00:47 -0700 Subject: [PATCH 02/65] Add new params --- src/quantum/azext_quantum/_params.py | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 5f662e0c7ca..34858ef3563 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -47,6 +47,16 @@ def load_arguments(self, _): provider_sku_list_type = CLIArgumentType(options_list=['--provider-sku-list', '-r'], help='Comma separated list of Provider/SKU pairs. Separate the Provider and SKU with a slash. Enclose the entire list in quotes. Values from `az quantum offerings list -l -o table`') auto_accept_type = CLIArgumentType(help='If specified, provider terms are accepted without an interactive Y/N prompt.') autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') + # >>>>> Finalize these names <<<<< + # Peter's names: + job_input_source_type = CLIArgumentType(help='The location of the QIR input file to submit. Defaults to current folder.') + job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') + job_output_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to [TBD].') + # Guen's names: + qir_payload_type = CLIArgumentType(help='The pathname of the QIR input file to submit.') + qir_endpoint_type = CLIArgumentType(help='The URL of the QIR endpoint.') + qir_param_type = CLIArgumentType(help='A QIR parameter. May be repeated.') + # <<<<< with self.argument_context('quantum workspace') as c: c.argument('workspace_name', workspace_name_type) @@ -74,6 +84,16 @@ def load_arguments(self, _): with self.argument_context('quantum job submit') as c: c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) + # >>>>> Finalize these names <<<<< + # Peter's proposed param names: + c.argument('job_input_source', job_input_source_type) + c.argument('job_input_format', job_input_format_type) + c.argument('job_output_format', job_output_format_type) + # Guen's proposed param names: + c.argument('qir_payload', qir_payload_type) + c.argument('qir_endpoint', qir_endpoint_type) + c.argument('qir_param', qir_param_type) + # <<<<< c.positional('program_args', program_args_type) with self.argument_context('quantum execute') as c: @@ -86,6 +106,16 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) + # >>>>> Finalize these names <<<<< + # Peter's proposed param names: + c.argument('job_input_source', job_input_source_type) + c.argument('job_input_format', job_input_format_type) + c.argument('job_output_format', job_output_format_type) + # Guen's proposed param names: + c.argument('qir_payload', qir_payload_type) + c.argument('qir_endpoint', qir_endpoint_type) + c.argument('qir_param', qir_param_type) + # <<<<< c.positional('program_args', program_args_type) with self.argument_context('quantum run') as c: @@ -98,6 +128,16 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) + # >>>>> Finalize these names <<<<< + # Peter's proposed param names: + c.argument('job_input_source', job_input_source_type) + c.argument('job_input_format', job_input_format_type) + c.argument('job_output_format', job_output_format_type) + # Guen's proposed param names: + c.argument('qir_payload', qir_payload_type) + c.argument('qir_endpoint', qir_endpoint_type) + c.argument('qir_param', qir_param_type) + # <<<<< c.positional('program_args', program_args_type) with self.argument_context('quantum offerings') as c: From 00df4e47ec725b2715fdf4a96aea4cce0498e250 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 2 Sep 2022 17:24:56 -0700 Subject: [PATCH 03/65] Splice in a new submit function, but keep using the old code for Q# --- src/quantum/azext_quantum/_params.py | 10 +++---- src/quantum/azext_quantum/operations/job.py | 29 +++++++++++++++++++-- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 34858ef3563..932547a5840 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -47,12 +47,12 @@ def load_arguments(self, _): provider_sku_list_type = CLIArgumentType(options_list=['--provider-sku-list', '-r'], help='Comma separated list of Provider/SKU pairs. Separate the Provider and SKU with a slash. Enclose the entire list in quotes. Values from `az quantum offerings list -l -o table`') auto_accept_type = CLIArgumentType(help='If specified, provider terms are accepted without an interactive Y/N prompt.') autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') - # >>>>> Finalize these names <<<<< - # Peter's names: + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: job_input_source_type = CLIArgumentType(help='The location of the QIR input file to submit. Defaults to current folder.') job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') job_output_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to [TBD].') - # Guen's names: + # Guen's proposed param names: qir_payload_type = CLIArgumentType(help='The pathname of the QIR input file to submit.') qir_endpoint_type = CLIArgumentType(help='The URL of the QIR endpoint.') qir_param_type = CLIArgumentType(help='A QIR parameter. May be repeated.') @@ -84,7 +84,7 @@ def load_arguments(self, _): with self.argument_context('quantum job submit') as c: c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> Finalize these names <<<<< + # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: c.argument('job_input_source', job_input_source_type) c.argument('job_input_format', job_input_format_type) @@ -128,7 +128,7 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> Finalize these names <<<<< + # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: c.argument('job_input_source', job_input_source_type) c.argument('job_input_format', job_input_format_type) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 1ca7b84dd6c..1f4ef64f76c 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -169,8 +169,33 @@ def _has_completed(job): def submit(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, - project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, - target_capability=None): + project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source=None, job_input_format=None, job_output_format=None, + # Guen's proposed param names: + qir_payload=None, qir_endpoint=None, qir_param=None, + ): +# def submit(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, +# project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, +# job_input_source=None, job_input_format=None, job_output_format=None, +# qir_payload=None, qir_endpoint=None, qir_param=None): + """ + Submit a quantum program to run on Azure Quantum. + """ + + # >>>>> TODO: add logic that determines what type of job we're running <<<<< + + # Submit a Q# project. [Keep using old code for Q# for now] + return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability) + + +# def submit(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, +# project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, +# target_capability=None): +def _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability): """ Submit a Q# project to run on Azure Quantum. """ From 0f09895008aa9a80e564fc485951faef643dc003 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 2 Sep 2022 17:37:32 -0700 Subject: [PATCH 04/65] Add TODO comment --- src/quantum/azext_quantum/_params.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 932547a5840..7b29fe011eb 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -106,7 +106,7 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> Finalize these names <<<<< + # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: c.argument('job_input_source', job_input_source_type) c.argument('job_input_format', job_input_format_type) From a224fe85ba227287856ce84a63b9fa605368c4ad Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 7 Sep 2022 11:15:58 -0700 Subject: [PATCH 05/65] Add logic for new parameter --- src/quantum/azext_quantum/operations/job.py | 32 +++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 1f4ef64f76c..6db6e1223a8 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -174,8 +174,7 @@ def submit(cmd, program_args, resource_group_name=None, workspace_name=None, loc # Peter's proposed param names: job_input_source=None, job_input_format=None, job_output_format=None, # Guen's proposed param names: - qir_payload=None, qir_endpoint=None, qir_param=None, - ): + qir_payload=None, qir_endpoint=None, qir_param=None): # def submit(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, # project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, # job_input_source=None, job_input_format=None, job_output_format=None, @@ -185,6 +184,15 @@ def submit(cmd, program_args, resource_group_name=None, workspace_name=None, loc """ # >>>>> TODO: add logic that determines what type of job we're running <<<<< + if job_input_source is not None: + # >>>>> + # >>>>> + # >>>>> + raise AzureInternalError(">>>>> Got a path for the QIR job: " + job_input_source + " <<<<<") + # <<<<< + # <<<<< + # <<<<< + # Submit a Q# project. [Keep using old code for Q# for now] return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, @@ -359,13 +367,27 @@ def wait(cmd, job_id, resource_group_name=None, workspace_name=None, location=No return job -def run(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, - project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None): +# def run(cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, +# project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None): +def run (cmd, program_args, resource_group_name=None, workspace_name=None, location=None, target_id=None, + project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source=None, job_input_format=None, job_output_format=None, + # Guen's proposed param names: + qir_payload=None, qir_endpoint=None, qir_param=None): """ Submit a job to run on Azure Quantum, and waits for the result. """ + # job = submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, + # project, job_name, shots, storage, no_build, job_params, target_capability) job = submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project, job_name, shots, storage, no_build, job_params, target_capability) + project, job_name, shots, storage, no_build, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_input_format, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param) logger.warning("Job id: %s", job.id) logger.debug(job) From 3a502f5355649b4e1cb3217b92f8023d8dba1154 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 14 Oct 2022 10:11:29 -0700 Subject: [PATCH 06/65] Temporarily add build number to version number --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index cc51ac7daca..a0e28e8efe7 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.17.0" +CLI_REPORTED_VERSION = "0.17.0.1" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 2343cb8117d..6ec07847d77 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.17.0' +VERSION = '0.17.0.1' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From 919a538e6f0c2333653747a7c47ca8339d73b86c Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 14 Oct 2022 11:55:01 -0700 Subject: [PATCH 07/65] In _submit_qir, raise error if --job-input-source is omitted --- src/quantum/azext_quantum/operations/job.py | 71 ++++++++++++--------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index aa6868d82a1..138f5e993bb 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -183,37 +183,48 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ + # Submit QIR + if job_input_format == "qir.v1": + return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_input_format, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param) + + # Submit a Q# project. (Do it the old way, for now.) + return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability) + + +def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_input_format, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param): - # # >>>>> Dummy code to show the job_input_source value <<<<< - # if job_input_source is not None: - # raise AzureInternalError(">>>>> Got a path for the QIR job: " + job_input_source + " <<<<<") - # # <<<<< - - -# # >>>>> Look at job_input_format value <<<<< -# if job_input_format is "qir.v1": -# return _submit_qir(???) - -# # Submit a Q# project. [Keep using old code for Q# for now] -# return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, -# project, job_name, shots, storage, no_build, job_params, target_capability) - - -# def _submit_qir(???): -# . -# . -# . - -# if result.returncode == 0: -# . -# . -# . -# return ??? - -# # The QIR job failed to run. -# logger.error("Submission of job failed with error code %s", result.returncode) -# print(result.stdout.decode('ascii')) -# raise AzureInternalError("Failed to submit job.") + """ + Submit a QIR program to run on Azure Quantum. + """ + if job_input_source is None: + raise AzureInternalError("Failed to submit QIR job: No --job-input-source path was specified.") + + # >>>>> For debug: Show the job_input_source value <<<<< + #raise AzureInternalError(">>>>> Got a path for the QIR job: " + job_input_source + " <<<<<") + # <<<<< + + # >>>>> Submit the QIR job here <<<<< + + # if result.returncode == 0: + # return # What data do we return? + + # The QIR job failed to run. + # logger.error("Submission of job failed with error code %s", result.returncode) + # print(result.stdout.decode('ascii')) + raise AzureInternalError("Failed to submit QIR job.") def _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, From f7066cbf5c8d02b661e8949b04a7d5aaf0579723 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 14 Oct 2022 18:08:20 -0700 Subject: [PATCH 08/65] Add help examples and more param validation logic --- src/quantum/azext_quantum/_help.py | 16 ++++--- src/quantum/azext_quantum/_params.py | 6 +-- src/quantum/azext_quantum/operations/job.py | 49 +++++++++++++++------ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/quantum/azext_quantum/_help.py b/src/quantum/azext_quantum/_help.py index 38301de1c45..62576e6b9cc 100644 --- a/src/quantum/azext_quantum/_help.py +++ b/src/quantum/azext_quantum/_help.py @@ -15,7 +15,7 @@ type: command short-summary: Submit a job to run on Azure Quantum, and waits for the result. examples: - - name: Submit the Q# program from the current folder and wait for the result. + - name: Submit a Q# program from the current folder and wait for the result. text: |- az quantum execute -g MyResourceGroup -w MyWorkspace -l MyLocation -t MyTarget - name: Submit and wait for a Q# program from the current folder with job and program parameters. @@ -32,7 +32,7 @@ type: command short-summary: Equivalent to `az quantum execute` examples: - - name: Submit the Q# program from the current folder and wait for the result. + - name: Submit a Q# program from the current folder and wait for the result. text: |- az quantum run -g MyResourceGroup -w MyWorkspace -l MyLocation -t MyTarget - name: Submit and wait for a Q# program from the current folder with job and program parameters. @@ -81,17 +81,21 @@ helps['quantum job submit'] = """ type: command - short-summary: Submit a Q# project to run on Azure Quantum. + short-summary: Submit a program or circuit to run on Azure Quantum. examples: - - name: Submit the Q# program from the current folder. + - name: Submit a Q# program from the current folder. text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ -t MyTarget --job-name MyJob - - name: Submit the Q# program from the current folder with job parameters for a target. + - name: Submit a QIR program or circuit from the current folder. + text: |- + az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ + -t MyTarget --job-name MyJob --job-input-format qir.v1 + - name: Submit a Q# program from the current folder with job parameters for a target. text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ -t MyTarget --job-name MyJob --job-params param1=value1 param2=value2 - - name: Submit the Q# program with program parameters (e.g. n-qubits = 2). + - name: Submit a Q# program with program parameters (e.g. n-qubits = 2). text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ -t MyTarget --job-name MyJob -- --n-qubits=2 diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index cf61586f540..811754b4072 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -55,12 +55,12 @@ def load_arguments(self, _): autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: - job_input_source_type = CLIArgumentType(help='The location of the QIR input file to submit. Defaults to current folder.') + job_input_source_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension based on --job-input-type') job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') - job_output_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to [TBD].') + job_output_format_type = CLIArgumentType(help='The expected job output format.') # Guen's proposed param names: qir_payload_type = CLIArgumentType(help='The pathname of the QIR input file to submit.') - qir_endpoint_type = CLIArgumentType(help='The URL of the QIR endpoint.') + qir_endpoint_type = CLIArgumentType(help='The URI of the QIR endpoint.') qir_param_type = CLIArgumentType(help='A QIR parameter. May be repeated.') # <<<<< diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 138f5e993bb..bb8f7aee3a8 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -8,15 +8,18 @@ import logging import json import knack.log +import os from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, - InvalidArgumentValueError, AzureResponseError) + InvalidArgumentValueError, AzureResponseError, + RequiredArgumentMissingError) from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo MINIMUM_MAX_POLL_WAIT_SECS = 1 +JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" logger = logging.getLogger(__name__) knack_logger = knack.log.get_logger(__name__) @@ -183,34 +186,52 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ - # Submit QIR - if job_input_format == "qir.v1": - return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_input_format, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param) + if job_input_format is not None: + if job_input_format.lower() == "qir.v1": + # Submit QIR + return _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param) + + # Add elifs to handle new job_input_format values here + + elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": + pass # Fall through, same as when job_input_format is None + + else: + raise InvalidArgumentValueError("Job input format not recognized: " + job_input_format, JOB_SUBMIT_DOC_LINK_MSG) # Submit a Q# project. (Do it the old way, for now.) return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability) -def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, +def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: - job_input_source, job_input_format, job_output_format, + job_input_source, job_output_format, # Guen's proposed param names: qir_payload, qir_endpoint, qir_param): """ - Submit a QIR program to run on Azure Quantum. + Submit a QIR program or circuit to run on Azure Quantum. """ if job_input_source is None: - raise AzureInternalError("Failed to submit QIR job: No --job-input-source path was specified.") + + # # If no filename of path was given, look in the current folder + # # example from https://stackoverflow.com/questions/45946148/find-a-file-from-a-partial-filename-in-python + # path = os.path.dirname(os.path.realpath(__file__)) + # for f_name in os.listdir(path): + # if f_name.endswith('.ll'): + # print('found a match') + + + raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) # >>>>> For debug: Show the job_input_source value <<<<< #raise AzureInternalError(">>>>> Got a path for the QIR job: " + job_input_source + " <<<<<") From 3e1e9ae2ff26542acea2eafc2ea222cf02f94965 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 17 Oct 2022 18:11:28 -0700 Subject: [PATCH 09/65] Add input file code --- src/quantum/azext_quantum/operations/job.py | 41 +++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index bb8f7aee3a8..d91c92669b0 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -222,25 +222,42 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat Submit a QIR program or circuit to run on Azure Quantum. """ if job_input_source is None: + # If no filename of path was given, look in the current folder + path = os.path.abspath(os.curdir) + for file_name in os.listdir(path): + if file_name.endswith('.ll'): + job_input_source = os.path.join(path, file_name) + break + if job_input_source is None: + raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) - # # If no filename of path was given, look in the current folder - # # example from https://stackoverflow.com/questions/45946148/find-a-file-from-a-partial-filename-in-python - # path = os.path.dirname(os.path.realpath(__file__)) - # for f_name in os.listdir(path): - # if f_name.endswith('.ll'): - # print('found a match') + # >>>>> For debug: Show the job_input_source value <<<<< + knack_logger.warning(">>>>> Got a path for the QIR input: " + job_input_source + " <<<<<") + # <<<<< - raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) - # >>>>> For debug: Show the job_input_source value <<<<< - #raise AzureInternalError(">>>>> Got a path for the QIR job: " + job_input_source + " <<<<<") + # >>>>> Upload the QIR file to the storage account + + # >>>>> For debug <<<<< + knack_logger.warning('>>>>> We should upload the QIR to storage now <<<<<') # <<<<< - # >>>>> Submit the QIR job here <<<<< - + + # >>>>> Code from output function, below... + # from azure.cli.command_modules.storage._client_factory import blob_data_service_factory + # path = os.path.join(tempfile.gettempdir(), job_id) + # info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + # client = cf_jobs(cmd.cli_ctx, info.subscription, info.resource_group, info.name, info.location) + + + # >>>>> Submit the QIR job <<<<< + + + + # if result.returncode == 0: - # return # What data do we return? + return # What data do we return? # The QIR job failed to run. # logger.error("Submission of job failed with error code %s", result.returncode) From 0d8648be33d696aac50476934923e3d9f7a5036d Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 18 Oct 2022 12:39:06 -0700 Subject: [PATCH 10/65] Add storage.py --- src/quantum/azext_quantum/operations/job.py | 131 +++++- .../azext_quantum/operations/storage.py | 383 ++++++++++++++++++ 2 files changed, 509 insertions(+), 5 deletions(-) create mode 100644 src/quantum/azext_quantum/operations/storage.py diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index d91c92669b0..a76c6e2a6e9 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -24,6 +24,59 @@ logger = logging.getLogger(__name__) knack_logger = knack.log.get_logger(__name__) +# >>>>> >>>>> +# >>>>> Code from top of qdk-python\azure-quantum\azure\quantum\workspace.py +# >>>>> qdk-python AutoREST client imports +# >>>>> +# from typing import Any, Dict, Iterable, List, Optional, TYPE_CHECKING, Tuple, Union +# from deprecated import deprecated + +# # Temporarily replacing the DefaultAzureCredential with +# # a custom _DefaultAzureCredential +# # from azure.identity import DefaultAzureCredential +# from azure.quantum._authentication import _DefaultAzureCredential + +# from azure.quantum._client import QuantumClient +# from azure.quantum._client.operations import ( +# JobsOperations, +# StorageOperations, +# QuotasOperations +# ) +# from azure.quantum._client.models import BlobDetails, JobStatus +# from azure.quantum import Job +# from azure.quantum.storage import create_container_using_client, get_container_uri, ContainerClient + +# from .version import __version__ + +# if TYPE_CHECKING: +# from azure.quantum._client.models import TargetStatus +# from azure.quantum.target import Target + +# logger = logging.getLogger(__name__) + +# __all__ = ["Workspace"] + +# DEFAULT_CONTAINER_NAME_FORMAT = "job-{job_id}" +# USER_AGENT_APPID_ENV_VAR_NAME = "AZURE_QUANTUM_PYTHON_APPID" +# <<<<< <<<<< +# >>>>> >>>>> +# >>>>> Imports modified for CLI extension AutoREST client files +# >>>>> +# from azure.quantum._client import QuantumClient <----<<< qdk-python path structure +from ..vendored_sdks.azure_quantum import QuantumClient + +from ..vendored_sdks.azure_quantum.operations import ( + JobsOperations, + StorageOperations, + QuotasOperations +) +from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus +from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python +from .storage import create_container_using_client, get_container_uri, ContainerClient +# <<<<< <<<<< + + + def list(cmd, resource_group_name, workspace_name, location): """ @@ -240,19 +293,87 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # >>>>> Upload the QIR file to the storage account # >>>>> For debug <<<<< - knack_logger.warning('>>>>> We should upload the QIR to storage now <<<<<') + knack_logger.warning(">>>>> We should upload the QIR to storage now <<<<<") # <<<<< - # >>>>> Code from output function, below... - # from azure.cli.command_modules.storage._client_factory import blob_data_service_factory - # path = os.path.join(tempfile.gettempdir(), job_id) + # >>>>> Code from old submit function (now renamed _submit_qsharp) with ws renamed ws_info: + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + target = TargetInfo(cmd, target_id) + token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token + # >>>>> + project = None # >>>>> Is this arg relevant for a QIR job? <<<<< + # <<<<< + args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) + _set_cli_version() + + + # >>>>> Code from output function, below, with info renamed ws_info... + import tempfile + import json + import os + from azure.cli.command_modules.storage._client_factory import blob_data_service_factory + + # >>>>> + job_id = "debug-qir-job-id-debug" + # <<<<< + output_path = os.path.join(tempfile.gettempdir(), job_id) + # >>>>> + knack_logger.warning(">>>>> path = " + output_path + " <<<<<") + # <<<<< # info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) # client = cf_jobs(cmd.cli_ctx, info.subscription, info.resource_group, info.name, info.location) + client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) + # job = client.get(job_id) + + # if os.path.exists(path): + # logger.debug("Using existing blob from %s", path) + # else: + # logger.debug("Downloading job results blob into %s", path) + + # if job.status != "Succeeded": + # return job # If "-o table" is specified, this allows transform_output() in commands.py + # # to format the output, so the error info is shown. If "-o json" or no "-o" + # # parameter is specified, then the full JSON job output is displayed, being + # # consistent with other commands. + + # args = _parse_blob_url(job.output_data_uri) + # blob_service = blob_data_service_factory(cmd.cli_ctx, args) + # blob_service.get_blob_to_path(args['container'], args['blob'], path) + + # >>>>> FIX THIS >>>>> + # >>>>> FIX THIS >>>>> + # >>>>> FIX THIS >>>>> + # job = client.create(job_id, job_details) # <-----<<< This fails. Where do we info for _models.JobDetails ?? + + + # >>>>> >>>>> For reference... + # def create( + # self, + # job_id, # type: str + # job, # type: _models.JobDetails + # **kwargs # type: Any + # ): + # # type: (...) -> _models.JobDetails + # """Create a job. + + # :param job_id: Id of the job. + # :type job_id: str + # :param job: The complete metadata of the job to submit. + # :type job: ~azure.quantum._client.models.JobDetails + # :keyword callable cls: A custom type or function that will be passed the direct response + # :return: JobDetails, or the result of cls(response) + # :rtype: ~azure.quantum._client.models.JobDetails + # :raises: ~azure.core.exceptions.HttpResponseError + # """ + # <<<<< <<<<< + - # >>>>> Submit the QIR job <<<<< + # >>>>> For debug <<<<< + knack_logger.warning(">>>>> Submit the QIR job now <<<<<") + # <<<<< diff --git a/src/quantum/azext_quantum/operations/storage.py b/src/quantum/azext_quantum/operations/storage.py new file mode 100644 index 00000000000..7ef88521455 --- /dev/null +++ b/src/quantum/azext_quantum/operations/storage.py @@ -0,0 +1,383 @@ +## +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +## +import logging +from typing import Any, Dict +from azure.core import exceptions +from azure.storage.blob import ( + BlobServiceClient, + ContainerClient, + BlobClient, + BlobSasPermissions, + ContentSettings, + generate_blob_sas, + generate_container_sas, + BlobType, +) +from datetime import datetime, timedelta +from enum import Enum + +logger = logging.getLogger(__name__) + + +def create_container( + connection_string: str, container_name: str +) -> ContainerClient: + """ + Creates and initialize a container; returns the client needed to access it. + """ + blob_service_client = BlobServiceClient.from_connection_string( + connection_string + ) + logger.info( + f'{"Initializing storage client for account:"}' + + f"{blob_service_client.account_name}" + ) + + container_client = blob_service_client.get_container_client(container_name) + create_container_using_client(container_client) + return container_client + + +def create_container_using_client(container_client: ContainerClient): + """ + Creates the container if it doesn't already exist. + """ + if not container_client.exists(): + logger.debug( + f'{" - uploading to **new** container:"}' + f"{container_client.container_name}" + ) + container_client.create_container() + + +def get_container_uri(connection_string: str, container_name: str) -> str: + """ + Creates and initialize a container; + returns a URI with a SAS read/write token to access it. + """ + container = create_container(connection_string, container_name) + logger.info( + f'{"Creating SAS token for container"}' + + f"'{container_name}' on account: '{container.account_name}'" + ) + + sas_token = generate_container_sas( + container.account_name, + container.container_name, + account_key=container.credential.account_key, + permission=BlobSasPermissions( + read=True, add=True, write=True, create=True + ), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + uri = container.url + "?" + sas_token + logger.debug(f" - container url: '{uri}'.") + return uri + + +def upload_blob( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Uploading blob '{blob_name}'" + + f"to container '{container.container_name}'" + + f"on account: '{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + + blob = container.get_blob_client(blob_name) + + blob.upload_blob(data, content_settings=content_settings) + logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") + + if return_sas_token: + uri = get_blob_uri_with_sas_token(blob) + else: + uri = remove_sas_token(blob.url) + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +def append_blob( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, + metadata: Dict[str, str] = None, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Appending data to blob '{blob_name}'" + + f"in container '{container.container_name}'" + + f"on account: '{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + blob = container.get_blob_client(blob_name) + try: + props = blob.get_blob_properties() + if props.blob_type != BlobType.AppendBlob: + raise Exception("blob must be an append blob") + except exceptions.ResourceNotFoundError: + props = blob.create_append_blob( + content_settings=content_settings, metadata=metadata + ) + + blob.append_block(data, len(data)) + logger.debug(f" - blob '{blob_name}' appended. generating sas token.") + + if return_sas_token: + uri = get_blob_uri_with_sas_token(blob) + else: + uri = remove_sas_token(blob.url) + + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +def get_blob_uri_with_sas_token(blob: BlobClient): + """Returns a URI for the given blob that contains a SAS Token""" + sas_token = generate_blob_sas( + blob.account_name, + blob.container_name, + blob.blob_name, + account_key=blob.credential.account_key, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + return blob.url + "?" + sas_token + + +def download_blob(blob_url: str) -> Any: + """ + Downloads the given blob from the container. + """ + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Downloading blob '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}'" + + f"on account: '{blob_client.account_name}'" + ) + + response = blob_client.download_blob().readall() + logger.debug(response) + + return response + + +def download_blob_properties(blob_url: str) -> Dict[str, str]: + """Downloads the blob properties from Azure for the given blob URI""" + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Downloading blob properties '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}'" + + f"on account: '{blob_client.account_name}'" + ) + + response = blob_client.get_blob_properties() + logger.debug(response) + + return response + + +def download_blob_metadata(blob_url: str) -> Dict[str, str]: + """Downloads the blob metadata from the + blob properties in Azure for the given blob URI""" + return download_blob_properties(blob_url).metadata + + +def set_blob_metadata(blob_url: str, metadata: Dict[str, str]): + """Sets the provided dictionary as the metadata on the Azure blob""" + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Setting blob properties '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}' on account:" + + f"'{blob_client.account_name}'" + ) + return blob_client.set_blob_metadata(metadata=metadata) + + +def remove_sas_token(sas_uri: str) -> str: + """Removes the SAS Token from the given URI if it contains one""" + index = sas_uri.find("?") + if index != -1: + sas_uri = sas_uri[0:index] + + return sas_uri + + +def init_blob_for_streaming_upload( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Streaming blob '{blob_name}'" + + f"to container '{container.container_name}' on account:" + + f"'{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + blob = container.get_blob_client(blob_name) + blob.stage_block() + blob.commit_block_list() + blob.upload_blob(data, content_settings=content_settings) + logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") + + if return_sas_token: + sas_token = generate_blob_sas( + blob.account_name, + blob.container_name, + blob.blob_name, + account_key=blob.credential.account_key, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + uri = blob.url + "?" + sas_token + else: + uri = remove_sas_token(blob.url) + + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +class StreamedBlobState(str, Enum): + not_initialized = 0 + uploading = 1 + committed = 2 + + +class StreamedBlob: + """Class that provides a state machine for writing + blobs using the Azure Block Blob API + + Internally implements a state machine for uploading blob data. + To use, start calling `upload_data()` + to add data blocks. Each call to `upload_data()` + will synchronously upload an individual block to Azure. + Once all blocks have been added, call `commit()` + to commit the blocks and make the blob available/readable. + + :param container: The container client that the blob will be uploaded to + :param blob_name: The name of the blob + (including optional path) within the blob container + :param content_type: The HTTP content type to apply to the blob metadata + :param content_encoding: The HTTP + content encoding to apply to the blob metadata + """ + + def __init__( + self, + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + ): + self.container = container + self.blob_name = blob_name + self.content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + self.state = StreamedBlobState.not_initialized + self.blob = container.get_blob_client(blob_name) + self.blocks = [] + + def upload_data(self, data): + """Synchronously uploads a block to the given block blob in Azure + + :param data: The data to be uploaded as a block. + :type data: Union[Iterable[AnyStr], IO[AnyStr]] + """ + if self.state == StreamedBlobState.not_initialized: + create_container_using_client(self.container) + logger.info( + f"Streaming blob '{self.blob_name}' to container" + + f"'{self.container.container_name}'" + + f"on account: '{self.container.account_name}'" + ) + self.initialized = True + + self.state = StreamedBlobState.uploading + id = self._get_next_block_id() + logger.debug(f"Uploading block '{id}' to {self.blob_name}") + self.blob.stage_block(id, data, length=len(data)) + self.blocks.append(id) + + def commit(self, metadata: Dict[str, str] = None): + """Synchronously commits all previously + uploaded blobs to the block blob + + :param metadata: Optional dictionary of + metadata to be applied to the block blob + """ + if self.state == StreamedBlobState.not_initialized: + raise Exception("StreamedBlob cannot commit before uploading data") + elif self.state == StreamedBlobState.committed: + raise Exception("StreamedBlob is already committed") + + logger.debug(f"Committing {len(self.blocks)} blocks {self.blob_name}") + self.blob.commit_block_list( + self.blocks, + content_settings=self.content_settings, + metadata=metadata, + ) + self.state = StreamedBlobState.committed + logger.debug(f"Committed {self.blob_name}") + + def getUri(self, with_sas_token: bool = False): + """Gets the full Azure Storage URI for the + uploaded blob after it has been committed""" + if self.state != StreamedBlobState.committed: + raise Exception("Can only retrieve sas token for committed blob") + if with_sas_token: + return get_blob_uri_with_sas_token(self.blob) + + return remove_sas_token(self.blob.url) + + def _get_next_block_id(self): + return f"{len(self.blocks):10}" From 43d4406f14c316ab70ff873751dcae6ff6560203 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 18 Oct 2022 14:48:19 -0700 Subject: [PATCH 11/65] Fix Flake8 style rule violations --- src/quantum/azext_quantum/operations/job.py | 96 ++++++++----------- .../azext_quantum/operations/storage.py | 4 +- 2 files changed, 42 insertions(+), 58 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index a76c6e2a6e9..07dd72a6fa0 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,6 +18,17 @@ from .workspace import WorkspaceInfo from .target import TargetInfo +from ..vendored_sdks.azure_quantum import QuantumClient +from ..vendored_sdks.azure_quantum.operations import ( + JobsOperations, + StorageOperations, + QuotasOperations +) +from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus +from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python +from .storage import create_container_using_client, get_container_uri, ContainerClient + + MINIMUM_MAX_POLL_WAIT_SECS = 1 JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" @@ -59,23 +70,6 @@ # DEFAULT_CONTAINER_NAME_FORMAT = "job-{job_id}" # USER_AGENT_APPID_ENV_VAR_NAME = "AZURE_QUANTUM_PYTHON_APPID" # <<<<< <<<<< -# >>>>> >>>>> -# >>>>> Imports modified for CLI extension AutoREST client files -# >>>>> -# from azure.quantum._client import QuantumClient <----<<< qdk-python path structure -from ..vendored_sdks.azure_quantum import QuantumClient - -from ..vendored_sdks.azure_quantum.operations import ( - JobsOperations, - StorageOperations, - QuotasOperations -) -from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus -from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python -from .storage import create_container_using_client, get_container_uri, ContainerClient -# <<<<< <<<<< - - def list(cmd, resource_group_name, workspace_name, location): @@ -241,35 +235,35 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ if job_input_format is not None: if job_input_format.lower() == "qir.v1": - # Submit QIR + # Submit QIR return _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param) + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param) # Add elifs to handle new job_input_format values here elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": - pass # Fall through, same as when job_input_format is None + pass # Fall through, same as when job_input_format is None else: raise InvalidArgumentValueError("Job input format not recognized: " + job_input_format, JOB_SUBMIT_DOC_LINK_MSG) # Submit a Q# project. (Do it the old way, for now.) return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project, job_name, shots, storage, no_build, job_params, target_capability) + project, job_name, shots, storage, no_build, job_params, target_capability) def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param): + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param): """ Submit a QIR program or circuit to run on Azure Quantum. @@ -288,26 +282,22 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat knack_logger.warning(">>>>> Got a path for the QIR input: " + job_input_source + " <<<<<") # <<<<< - - # >>>>> Upload the QIR file to the storage account # >>>>> For debug <<<<< knack_logger.warning(">>>>> We should upload the QIR to storage now <<<<<") # <<<<< - # >>>>> Code from old submit function (now renamed _submit_qsharp) with ws renamed ws_info: - ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - target = TargetInfo(cmd, target_id) - token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token + # >>>>> Commented out for Flake8 >>>>>ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + # >>>>> Commented out for Flake8 >>>>>target = TargetInfo(cmd, target_id) + # >>>>> Commented out for Flake8 >>>>>token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token # >>>>> - project = None # >>>>> Is this arg relevant for a QIR job? <<<<< + # >>>>> Commented out for Flake8 >>>>>project = None # >>>>> Is this arg relevant for a QIR job? <<<<< # <<<<< - args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) + # >>>>> Commented out for Flake8 >>>>>args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) _set_cli_version() - # >>>>> Code from output function, below, with info renamed ws_info... import tempfile import json @@ -323,7 +313,7 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # <<<<< # info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) # client = cf_jobs(cmd.cli_ctx, info.subscription, info.resource_group, info.name, info.location) - client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) + # >>>>> Commented out for Flake8 >>>>>client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) # job = client.get(job_id) # if os.path.exists(path): @@ -346,7 +336,6 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # >>>>> FIX THIS >>>>> # job = client.create(job_id, job_details) # <-----<<< This fails. Where do we info for _models.JobDetails ?? - # >>>>> >>>>> For reference... # def create( # self, @@ -368,17 +357,12 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # """ # <<<<< <<<<< - - - # >>>>> For debug <<<<< knack_logger.warning(">>>>> Submit the QIR job now <<<<<") # <<<<< - - # if result.returncode == 0: - return # What data do we return? + return # What data do we return? # The QIR job failed to run. # logger.error("Submission of job failed with error code %s", result.returncode) @@ -551,7 +535,7 @@ def wait(cmd, job_id, resource_group_name, workspace_name, location, max_poll_wa return job -def job_show (cmd, job_id, resource_group_name, workspace_name, location): +def job_show(cmd, job_id, resource_group_name, workspace_name, location): """ Get the job's status and details. """ @@ -562,12 +546,12 @@ def job_show (cmd, job_id, resource_group_name, workspace_name, location): def run(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source=None, job_input_format=None, job_output_format=None, - # Guen's proposed param names: - qir_payload=None, qir_endpoint=None, qir_param=None): + project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source=None, job_input_format=None, job_output_format=None, + # Guen's proposed param names: + qir_payload=None, qir_endpoint=None, qir_param=None): """ Submit a job to run on Azure Quantum, and wait for the result. """ diff --git a/src/quantum/azext_quantum/operations/storage.py b/src/quantum/azext_quantum/operations/storage.py index 7ef88521455..23eda0a0673 100644 --- a/src/quantum/azext_quantum/operations/storage.py +++ b/src/quantum/azext_quantum/operations/storage.py @@ -102,9 +102,9 @@ def upload_blob( content_settings = ContentSettings( content_type=content_type, content_encoding=content_encoding ) - + blob = container.get_blob_client(blob_name) - + blob.upload_blob(data, content_settings=content_settings) logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") From 61251c6a55e7f1253125200a25e7b34ad3cd8028 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 18 Oct 2022 17:35:53 -0700 Subject: [PATCH 12/65] Clean up some comments and add code for debugging --- src/quantum/azext_quantum/operations/job.py | 28 +++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 07dd72a6fa0..c2fdb82dab4 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -289,14 +289,13 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # <<<<< # >>>>> Code from old submit function (now renamed _submit_qsharp) with ws renamed ws_info: - # >>>>> Commented out for Flake8 >>>>>ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - # >>>>> Commented out for Flake8 >>>>>target = TargetInfo(cmd, target_id) - # >>>>> Commented out for Flake8 >>>>>token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token - # >>>>> - # >>>>> Commented out for Flake8 >>>>>project = None # >>>>> Is this arg relevant for a QIR job? <<<<< - # <<<<< - # >>>>> Commented out for Flake8 >>>>>args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) - _set_cli_version() + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + # >>>>> This code works (no errors) but is commented out because Flake8 doesn't like variables that are assigned and never used >>>>> + # target = TargetInfo(cmd, target_id) + # token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token + # project = None # >>>>> Is this arg relevant for a QIR job? <<<<< + # args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) + # _set_cli_version() # Sets the USER_AGENT environment variable # >>>>> Code from output function, below, with info renamed ws_info... import tempfile @@ -313,7 +312,16 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # <<<<< # info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) # client = cf_jobs(cmd.cli_ctx, info.subscription, info.resource_group, info.name, info.location) - # >>>>> Commented out for Flake8 >>>>>client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) + client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) + + # >>>>> Debug code... + if client is None: + knack_logger.warning(">>>>> Client is None <<<<<") + else: + knack_logger.warning(">>>>> Client is type " + str(type(client)) + " <<<<<") + # <<<<< + + # >>>>> The next line gets a "(JobNotFound) Job cannot be found" error >>>>> # job = client.get(job_id) # if os.path.exists(path): @@ -331,8 +339,6 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # blob_service = blob_data_service_factory(cmd.cli_ctx, args) # blob_service.get_blob_to_path(args['container'], args['blob'], path) - # >>>>> FIX THIS >>>>> - # >>>>> FIX THIS >>>>> # >>>>> FIX THIS >>>>> # job = client.create(job_id, job_details) # <-----<<< This fails. Where do we info for _models.JobDetails ?? From 9d833e23803340171c73ba015867cf54dda7ddf1 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 21 Oct 2022 17:11:15 -0700 Subject: [PATCH 13/65] Add code to Upload QIR file and submit job --- src/quantum/azext_quantum/operations/job.py | 141 +++++++------------- 1 file changed, 50 insertions(+), 91 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index c2fdb82dab4..8a9a1f286aa 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -9,6 +9,7 @@ import json import knack.log import os +import uuid from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, InvalidArgumentValueError, AzureResponseError, @@ -26,7 +27,7 @@ ) from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python -from .storage import create_container_using_client, get_container_uri, ContainerClient +from .storage import create_container, create_container_using_client, get_container_uri, ContainerClient, upload_blob MINIMUM_MAX_POLL_WAIT_SECS = 1 @@ -268,8 +269,11 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat """ Submit a QIR program or circuit to run on Azure Quantum. """ + if job_output_format is None: + job_output_format = "microsoft.quantum-results.v1" + if job_input_source is None: - # If no filename of path was given, look in the current folder + # If no pathname was specified, look for a QIR file in the current folder path = os.path.abspath(os.curdir) for file_name in os.listdir(path): if file_name.endswith('.ll'): @@ -278,102 +282,57 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat if job_input_source is None: raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) - # >>>>> For debug: Show the job_input_source value <<<<< - knack_logger.warning(">>>>> Got a path for the QIR input: " + job_input_source + " <<<<<") - # <<<<< - - # >>>>> Upload the QIR file to the storage account - - # >>>>> For debug <<<<< - knack_logger.warning(">>>>> We should upload the QIR to storage now <<<<<") + # Upload the QIR file to the workspace's storage account + # knack_logger.warning("Uploading the QIR file the Azure Storage account...") + + # >>>>> Temporarily use a hard-coded connection string <<<<< + connection_string = + + container_name = "cli-qir-job-" + str(uuid.uuid4()) # <<<<< Should this start with "quantum-job"? <<<<< + + container_client = create_container(connection_string, container_name) + blob_name = "inputData" + content_type = "qir.v1" + content_encoding = "utf-8" + return_sas_token = True + + # Open the QIR input file and upload it to a blob + with open(job_input_source, encoding="utf-8") as qir_file: + blob_data = qir_file.read() + blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) + + # >>>>> What about "submit args"? + # >>>>> Code from old submit function, renamed _submit_qsharp, below. Where does this go? >>>>> + # ws = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + # target = TargetInfo(cmd, target_id) + # token = _get_data_credentials(cmd.cli_ctx, ws.subscription).get_token().token + # + # args = _generate_submit_args(program_args, ws, target, token, project, job_name, shots, storage, job_params) + # _set_cli_version() # <<<<< - # >>>>> Code from old submit function (now renamed _submit_qsharp) with ws renamed ws_info: + # Submit the job + start_of_blob_name = blob_uri.find(blob_name) + container_uri = blob_uri[0:start_of_blob_name - 1] + "?" + blob_uri.split('?')[1] ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - # >>>>> This code works (no errors) but is commented out because Flake8 doesn't like variables that are assigned and never used >>>>> - # target = TargetInfo(cmd, target_id) - # token = _get_data_credentials(cmd.cli_ctx, ws_info.subscription).get_token().token - # project = None # >>>>> Is this arg relevant for a QIR job? <<<<< - # args = _generate_submit_args(program_args, ws_info, target, token, project, job_name, shots, storage, job_params) - # _set_cli_version() # Sets the USER_AGENT environment variable - - # >>>>> Code from output function, below, with info renamed ws_info... - import tempfile - import json - import os - from azure.cli.command_modules.storage._client_factory import blob_data_service_factory - - # >>>>> - job_id = "debug-qir-job-id-debug" - # <<<<< - output_path = os.path.join(tempfile.gettempdir(), job_id) - # >>>>> - knack_logger.warning(">>>>> path = " + output_path + " <<<<<") - # <<<<< - # info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - # client = cf_jobs(cmd.cli_ctx, info.subscription, info.resource_group, info.name, info.location) + target_info = TargetInfo(cmd, target_id) + job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) + job_details = {'container_uri': container_uri, + 'input_data_format': 'irq.v1', + 'output_data_format': job_output_format, + 'provider_id': target_info.target_id.split('.')[0], + 'target': target_info.target_id} + job = client.create(job_id, job_details) - # >>>>> Debug code... - if client is None: - knack_logger.warning(">>>>> Client is None <<<<<") - else: - knack_logger.warning(">>>>> Client is type " + str(type(client)) + " <<<<<") - # <<<<< - - # >>>>> The next line gets a "(JobNotFound) Job cannot be found" error >>>>> - # job = client.get(job_id) - - # if os.path.exists(path): - # logger.debug("Using existing blob from %s", path) - # else: - # logger.debug("Downloading job results blob into %s", path) - - # if job.status != "Succeeded": - # return job # If "-o table" is specified, this allows transform_output() in commands.py - # # to format the output, so the error info is shown. If "-o json" or no "-o" - # # parameter is specified, then the full JSON job output is displayed, being - # # consistent with other commands. - - # args = _parse_blob_url(job.output_data_uri) - # blob_service = blob_data_service_factory(cmd.cli_ctx, args) - # blob_service.get_blob_to_path(args['container'], args['blob'], path) - - # >>>>> FIX THIS >>>>> - # job = client.create(job_id, job_details) # <-----<<< This fails. Where do we info for _models.JobDetails ?? - - # >>>>> >>>>> For reference... - # def create( - # self, - # job_id, # type: str - # job, # type: _models.JobDetails - # **kwargs # type: Any - # ): - # # type: (...) -> _models.JobDetails - # """Create a job. - - # :param job_id: Id of the job. - # :type job_id: str - # :param job: The complete metadata of the job to submit. - # :type job: ~azure.quantum._client.models.JobDetails - # :keyword callable cls: A custom type or function that will be passed the direct response - # :return: JobDetails, or the result of cls(response) - # :rtype: ~azure.quantum._client.models.JobDetails - # :raises: ~azure.core.exceptions.HttpResponseError - # """ - # <<<<< <<<<< - - # >>>>> For debug <<<<< - knack_logger.warning(">>>>> Submit the QIR job now <<<<<") + # >>>>> + # # job = client.get(job_id) + # knack_logger.warning(f"Job Status: {job.status}") + # knack_logger.warning(f"Job ID: {job_id}") # <<<<< - # if result.returncode == 0: - return # What data do we return? - - # The QIR job failed to run. - # logger.error("Submission of job failed with error code %s", result.returncode) - # print(result.stdout.decode('ascii')) - raise AzureInternalError("Failed to submit QIR job.") + # >>>>> Do we need any logic based on status here? <<<<< + return job def _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, From abf06566b8102d69428bd5275fff240ae03950b5 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 26 Oct 2022 18:29:02 -0700 Subject: [PATCH 14/65] Accept various input formats --- src/quantum/azext_quantum/operations/job.py | 110 +++++++++++++++----- 1 file changed, 86 insertions(+), 24 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 8a9a1f286aa..8adefe9eef2 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -235,34 +235,78 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar Submit a quantum program to run on Azure Quantum. """ if job_input_format is not None: - if job_input_format.lower() == "qir.v1": - # Submit QIR - return _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param) - - # Add elifs to handle new job_input_format values here - - elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": - pass # Fall through, same as when job_input_format is None - - else: - raise InvalidArgumentValueError("Job input format not recognized: " + job_input_format, JOB_SUBMIT_DOC_LINK_MSG) + # # if job_input_format.lower() == "qir.v1": + # if "-ir.v" in job_input_format.lower(): + # # Submit QIR + # return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # # >>>>> TODO: Finalize these names <<<<< + # # Peter's proposed param names: + # job_input_source, job_input_format, job_output_format, + # # Guen's proposed param names: + # qir_payload, qir_endpoint, qir_param) + + # Submit QIR + return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + # >>>>> TODO: Finalize these names <<<<< + # Peter's proposed param names: + job_input_source, job_input_format, job_output_format, + # Guen's proposed param names: + qir_payload, qir_endpoint, qir_param) + + # # Add elifs to handle new job_input_format values here + + # elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": + # pass # Fall through, same as when job_input_format is None + + # else: + # raise InvalidArgumentValueError("Job input format not recognized: " + job_input_format, JOB_SUBMIT_DOC_LINK_MSG) # Submit a Q# project. (Do it the old way, for now.) return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability) -def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, location, target_id, +# # >>>>> This doesn't work -- It needs to generate JSON >>>>> >>>>> >>>>> +# def _generate_qir_submit_args(program_args, job_name, shots, job_params): +# """ Generates the list of arguments for submitting a QIR job """ + +# args = [] + +# if job_name: +# args.append("--job-name") +# args.append(job_name) + +# if shots: +# args.append("--shots") +# args.append(shots) + +# args.append("--user-agent") +# args.append("CLI") + +# if job_params: +# args.append("--job-params") +# for k, v in job_params.items(): +# if isinstance(v, str): +# # If value is string type already, do not use json.dumps(), since it will add extra escapes to the string +# args.append(f"{k}={v}") +# else: +# args.append(f"{k}={json.dumps(v)}") + +# args.extend(program_args) + +# logger.debug("Submitting QIR job with the following arguments:") +# logger.debug(args) + +# return args +# # <<<<< <<<<< <<<<< <<<<< + +def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, # >>>>> TODO: Finalize these names <<<<< # Peter's proposed param names: - job_input_source, job_output_format, + job_input_source, job_input_format, job_output_format, # Guen's proposed param names: qir_payload, qir_endpoint, qir_param): @@ -292,7 +336,8 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat container_client = create_container(connection_string, container_name) blob_name = "inputData" - content_type = "qir.v1" + # content_type = "qir.v1" + content_type = job_input_format content_encoding = "utf-8" return_sas_token = True @@ -301,7 +346,9 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat blob_data = qir_file.read() blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) - # >>>>> What about "submit args"? + # Set the job parameters + + # >>>>> What about "submit args"? Where should we handle other command parameters? # >>>>> Code from old submit function, renamed _submit_qsharp, below. Where does this go? >>>>> # ws = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) # target = TargetInfo(cmd, target_id) @@ -310,19 +357,34 @@ def _submit_qir_v1(cmd, program_args, resource_group_name, workspace_name, locat # args = _generate_submit_args(program_args, ws, target, token, project, job_name, shots, storage, job_params) # _set_cli_version() # <<<<< + # + # args = _generate_qir_submit_args(program_args, job_name, shots, job_params) - # Submit the job start_of_blob_name = blob_uri.find(blob_name) container_uri = blob_uri[0:start_of_blob_name - 1] + "?" + blob_uri.split('?')[1] ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) + # >>>>> Not sure what this line in the spec example was supposed to be. The arguments[] syntax doesn't work >>>>> + # input_params = {arguments[],'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} + # input_params = {"arguments[]":"",'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} + # input_params = {'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} + input_params = {'targetCapability': target_capability, 'shots': shots} + # <<<<< + job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) - job_details = {'container_uri': container_uri, - 'input_data_format': 'irq.v1', + job_details = {'container_uri': container_uri, # >>>>> See vendored_sdks\azure_quantum\models\_models_py3.py, line 132 + 'input_data_format': job_input_format, + # 'input_data_format': 'application/x-microsoft.ionq-ir.v3', + # 'input_data_format': 'ionq-ir.v3', + # 'input_data_format': 'application/json', 'output_data_format': job_output_format, + 'inputParams': input_params, + # 'inputParams': args, 'provider_id': target_info.target_id.split('.')[0], 'target': target_info.target_id} + + # Submit the job job = client.create(job_id, job_details) # >>>>> From 8f6202d778fa306f622f8909ed5a3d008a5b2175 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 27 Oct 2022 18:11:15 -0700 Subject: [PATCH 15/65] Modify inputParams --- src/quantum/azext_quantum/operations/job.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 8adefe9eef2..b0a347790c4 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -364,23 +364,17 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location container_uri = blob_uri[0:start_of_blob_name - 1] + "?" + blob_uri.split('?')[1] ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) - # >>>>> Not sure what this line in the spec example was supposed to be. The arguments[] syntax doesn't work >>>>> - # input_params = {arguments[],'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} - # input_params = {"arguments[]":"",'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} - # input_params = {'targetCapability':'FullComputation','entryPoint':'QuantumRNG__GenerateRandomBits','shots':'500'} - input_params = {'targetCapability': target_capability, 'shots': shots} + # >>>>> + # input_params = {'arguments':[], 'targetCapability': target_capability, 'shots': shots,'entryPoint':'Qrng__SampleQuantumRandomNumberGenerator'} + input_params = {'arguments':[], 'targetCapability': 'AdaptiveExecution', 'shots': 250,'entryPoint':'Qrng__SampleQuantumRandomNumberGenerator'} # <<<<< job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'container_uri': container_uri, # >>>>> See vendored_sdks\azure_quantum\models\_models_py3.py, line 132 'input_data_format': job_input_format, - # 'input_data_format': 'application/x-microsoft.ionq-ir.v3', - # 'input_data_format': 'ionq-ir.v3', - # 'input_data_format': 'application/json', 'output_data_format': job_output_format, 'inputParams': input_params, - # 'inputParams': args, 'provider_id': target_info.target_id.split('.')[0], 'target': target_info.target_id} From 80f0e862fafdb4da65ce2e90a59168583253da18 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 28 Oct 2022 19:25:47 -0700 Subject: [PATCH 16/65] Upload QIR bitcode --- src/quantum/azext_quantum/operations/job.py | 30 +++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index b0a347790c4..ca54e372b20 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -11,6 +11,7 @@ import os import uuid +from azure.cli.command_modules.storage.operations.account import show_storage_account_connection_string from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) @@ -27,6 +28,8 @@ ) from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python + +# >>>>> >>>>> Import these functions from qdk-python and remove the local copy of storage.py <<<<< <<<<< from .storage import create_container, create_container_using_client, get_container_uri, ContainerClient, upload_blob @@ -268,7 +271,7 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar project, job_name, shots, storage, no_build, job_params, target_capability) -# # >>>>> This doesn't work -- It needs to generate JSON >>>>> >>>>> >>>>> +# # >>>>> This doesn't work for submitting QIR -- It needs to generate JSON >>>>> >>>>> >>>>> # def _generate_qir_submit_args(program_args, job_name, shots, job_params): # """ Generates the list of arguments for submitting a QIR job """ @@ -327,22 +330,21 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) # Upload the QIR file to the workspace's storage account - # knack_logger.warning("Uploading the QIR file the Azure Storage account...") - - # >>>>> Temporarily use a hard-coded connection string <<<<< - connection_string = - - container_name = "cli-qir-job-" + str(uuid.uuid4()) # <<<<< Should this start with "quantum-job"? <<<<< - + if storage is None: + # >>>>> Look up the storage account name here <<<<< + storage = "vwjonesstorage2" + # <<<<< + + connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) + connection_string = connection_string_dict["connectionString"] + container_name = "cli-qir-job-" + str(uuid.uuid4()) # <<<<< Should this start with "quantum-job"? <<<<< container_client = create_container(connection_string, container_name) blob_name = "inputData" - # content_type = "qir.v1" - content_type = job_input_format - content_encoding = "utf-8" + # content_type = job_input_format + content_type = "application/x-qir.v1" # <<<<<< This is what a Q# executable sets for the inputData blob, but "qir.v1" is shown in the inputParams + content_encoding = None return_sas_token = True - - # Open the QIR input file and upload it to a blob - with open(job_input_source, encoding="utf-8") as qir_file: + with open(job_input_source, "rb") as qir_file: blob_data = qir_file.read() blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) From 2d2317be14100934583705d82bb17a408beac037 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 31 Oct 2022 18:08:25 -0700 Subject: [PATCH 17/65] Add --entry-point parameter --- src/quantum/azext_quantum/_help.py | 8 +- src/quantum/azext_quantum/_params.py | 44 ++--- src/quantum/azext_quantum/operations/job.py | 180 +++++++------------- 3 files changed, 80 insertions(+), 152 deletions(-) diff --git a/src/quantum/azext_quantum/_help.py b/src/quantum/azext_quantum/_help.py index 62576e6b9cc..941868ef7d6 100644 --- a/src/quantum/azext_quantum/_help.py +++ b/src/quantum/azext_quantum/_help.py @@ -87,10 +87,6 @@ text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ -t MyTarget --job-name MyJob - - name: Submit a QIR program or circuit from the current folder. - text: |- - az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ - -t MyTarget --job-name MyJob --job-input-format qir.v1 - name: Submit a Q# program from the current folder with job parameters for a target. text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ @@ -103,6 +99,10 @@ text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation -t MyTarget \\ --target-capability MyTargetCapability + - name: Submit QIR bitcode from the current folder. + text: |- + az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ + -t MyTarget --job-name MyJob --job-input-format qir.v1 --entry-point MyQirEntryPoint """ helps['quantum job wait'] = """ diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 811754b4072..a48e02f065b 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -53,16 +53,11 @@ def load_arguments(self, _): provider_sku_list_type = CLIArgumentType(options_list=['--provider-sku-list', '-r'], help='Comma separated list of Provider/SKU pairs. Separate the Provider and SKU with a slash. Enclose the entire list in quotes. Values from `az quantum offerings list -l -o table`') auto_accept_type = CLIArgumentType(help='If specified, provider terms are accepted without an interactive Y/N prompt.') autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension based on --job-input-type') + # job_input_source_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension is based on --job-input-type') + job_input_file_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension is based on --job-input-type') job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') job_output_format_type = CLIArgumentType(help='The expected job output format.') - # Guen's proposed param names: - qir_payload_type = CLIArgumentType(help='The pathname of the QIR input file to submit.') - qir_endpoint_type = CLIArgumentType(help='The URI of the QIR endpoint.') - qir_param_type = CLIArgumentType(help='A QIR parameter. May be repeated.') - # <<<<< + entry_point_type = CLIArgumentType(help='The entry point for the QIR program or circuit. Required for QIR. Ignored for Q# projects.') with self.argument_context('quantum workspace') as c: c.argument('workspace_name', workspace_name_type) @@ -94,16 +89,11 @@ def load_arguments(self, _): with self.argument_context('quantum job submit') as c: c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - c.argument('job_input_source', job_input_source_type) + # c.argument('job_input_source', job_input_source_type) + c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) - # Guen's proposed param names: - c.argument('qir_payload', qir_payload_type) - c.argument('qir_endpoint', qir_endpoint_type) - c.argument('qir_param', qir_param_type) - # <<<<< + c.argument('entry_point', entry_point_type) c.positional('program_args', program_args_type) with self.argument_context('quantum execute') as c: @@ -116,16 +106,11 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - c.argument('job_input_source', job_input_source_type) + # c.argument('job_input_source', job_input_source_type) + c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) - # Guen's proposed param names: - c.argument('qir_payload', qir_payload_type) - c.argument('qir_endpoint', qir_endpoint_type) - c.argument('qir_param', qir_param_type) - # <<<<< + c.argument('entry_point', entry_point_type) c.positional('program_args', program_args_type) with self.argument_context('quantum run') as c: @@ -138,16 +123,11 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - c.argument('job_input_source', job_input_source_type) + # c.argument('job_input_source', job_input_source_type) + c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) - # Guen's proposed param names: - c.argument('qir_payload', qir_payload_type) - c.argument('qir_endpoint', qir_endpoint_type) - c.argument('qir_param', qir_param_type) - # <<<<< + c.argument('entry_point', entry_point_type) c.positional('program_args', program_args_type) with self.argument_context('quantum offerings') as c: diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index ca54e372b20..a114dd4c9bf 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -7,9 +7,9 @@ import logging import json -import knack.log import os import uuid +import knack.log from azure.cli.command_modules.storage.operations.account import show_storage_account_connection_string from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, @@ -20,17 +20,18 @@ from .workspace import WorkspaceInfo from .target import TargetInfo -from ..vendored_sdks.azure_quantum import QuantumClient -from ..vendored_sdks.azure_quantum.operations import ( - JobsOperations, - StorageOperations, - QuotasOperations -) +# from ..vendored_sdks.azure_quantum import QuantumClient +# from ..vendored_sdks.azure_quantum.operations import ( +# JobsOperations, +# StorageOperations, +# QuotasOperations +# ) from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python # >>>>> >>>>> Import these functions from qdk-python and remove the local copy of storage.py <<<<< <<<<< -from .storage import create_container, create_container_using_client, get_container_uri, ContainerClient, upload_blob +# from .storage import create_container, create_container_using_client, get_container_uri, ContainerClient, upload_blob +from .storage import create_container, upload_blob MINIMUM_MAX_POLL_WAIT_SECS = 1 @@ -229,151 +230,104 @@ def _has_completed(job): def submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source=None, job_input_format=None, job_output_format=None, - # Guen's proposed param names: - qir_payload=None, qir_endpoint=None, qir_param=None): + # job_input_source=None, job_input_format=None, job_output_format=None, + job_input_file=None, job_input_format=None, job_output_format=None, + entry_point=None): """ Submit a quantum program to run on Azure Quantum. """ if job_input_format is not None: - # # if job_input_format.lower() == "qir.v1": - # if "-ir.v" in job_input_format.lower(): - # # Submit QIR - # return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # # >>>>> TODO: Finalize these names <<<<< - # # Peter's proposed param names: - # job_input_source, job_input_format, job_output_format, - # # Guen's proposed param names: - # qir_payload, qir_endpoint, qir_param) - - # Submit QIR - return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_input_format, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param) - - # # Add elifs to handle new job_input_format values here - - # elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": - # pass # Fall through, same as when job_input_format is None - - # else: - # raise InvalidArgumentValueError("Job input format not recognized: " + job_input_format, JOB_SUBMIT_DOC_LINK_MSG) - - # Submit a Q# project. (Do it the old way, for now.) - return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project, job_name, shots, storage, no_build, job_params, target_capability) - - -# # >>>>> This doesn't work for submitting QIR -- It needs to generate JSON >>>>> >>>>> >>>>> -# def _generate_qir_submit_args(program_args, job_name, shots, job_params): -# """ Generates the list of arguments for submitting a QIR job """ - -# args = [] + if job_input_format.lower() == "qir.v1": + # Submit QIR + return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + # job_input_source, job_input_format, job_output_format, + job_input_file, job_input_format, job_output_format, + entry_point) -# if job_name: -# args.append("--job-name") -# args.append(job_name) + # Add elifs here to handle new job_input_format values -# if shots: -# args.append("--shots") -# args.append(shots) + elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": + pass # Fall through, same as when job_input_format is None -# args.append("--user-agent") -# args.append("CLI") - -# if job_params: -# args.append("--job-params") -# for k, v in job_params.items(): -# if isinstance(v, str): -# # If value is string type already, do not use json.dumps(), since it will add extra escapes to the string -# args.append(f"{k}={v}") -# else: -# args.append(f"{k}={json.dumps(v)}") - -# args.extend(program_args) + else: + raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) -# logger.debug("Submitting QIR job with the following arguments:") -# logger.debug(args) + # Submit a Q# project. (Do it the old way, for now.) + return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability) -# return args -# # <<<<< <<<<< <<<<< <<<<< def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_input_format, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param): + # job_input_source, job_input_format, job_output_format, + job_input_file, job_input_format, job_output_format, + entry_point): """ - Submit a QIR program or circuit to run on Azure Quantum. + Submit QIR bitcode for a quantum program or circuit to run on Azure Quantum. """ if job_output_format is None: job_output_format = "microsoft.quantum-results.v1" - if job_input_source is None: - # If no pathname was specified, look for a QIR file in the current folder + # if job_input_source is None: + if job_input_file is None: + # If no pathname was specified, look for a QIR bitcode file in the current folder path = os.path.abspath(os.curdir) for file_name in os.listdir(path): - if file_name.endswith('.ll'): - job_input_source = os.path.join(path, file_name) + if file_name.endswith('.bc'): + # job_input_source = os.path.join(path, file_name) + job_input_file = os.path.join(path, file_name) break - if job_input_source is None: + # if job_input_source is None: + # raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) + if job_input_file is None: raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) # Upload the QIR file to the workspace's storage account if storage is None: - # >>>>> Look up the storage account name here <<<<< + # >>>>> Look up the storage account name here <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< storage = "vwjonesstorage2" - # <<<<< + # <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] - container_name = "cli-qir-job-" + str(uuid.uuid4()) # <<<<< Should this start with "quantum-job"? <<<<< + container_name = "cli-qir-job-" + str(uuid.uuid4()) container_client = create_container(connection_string, container_name) blob_name = "inputData" - # content_type = job_input_format - content_type = "application/x-qir.v1" # <<<<<< This is what a Q# executable sets for the inputData blob, but "qir.v1" is shown in the inputParams + content_type = "application/x-qir.v1" # This is what a Q# executable sets for the inputData blob, but "qir.v1" is shown in the inputParams content_encoding = None - return_sas_token = True - with open(job_input_source, "rb") as qir_file: + return_sas_token = False + # with open(job_input_source, "rb") as qir_file: + with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) # Set the job parameters - - # >>>>> What about "submit args"? Where should we handle other command parameters? - # >>>>> Code from old submit function, renamed _submit_qsharp, below. Where does this go? >>>>> - # ws = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - # target = TargetInfo(cmd, target_id) - # token = _get_data_credentials(cmd.cli_ctx, ws.subscription).get_token().token - # - # args = _generate_submit_args(program_args, ws, target, token, project, job_name, shots, storage, job_params) - # _set_cli_version() - # <<<<< - # - # args = _generate_qir_submit_args(program_args, job_name, shots, job_params) - start_of_blob_name = blob_uri.find(blob_name) - container_uri = blob_uri[0:start_of_blob_name - 1] + "?" + blob_uri.split('?')[1] + container_uri = blob_uri[0:start_of_blob_name - 1] ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) + + # Convert the --shots string to an integer + if shots is not None: + error_msg = "--shots value is not valid." + recommendation = "Enter a positive integer." + try: + shots = int(shots) + if shots < 1: + raise InvalidArgumentValueError(error_msg, recommendation) + except: + raise InvalidArgumentValueError(error_msg, recommendation) + # >>>>> - # input_params = {'arguments':[], 'targetCapability': target_capability, 'shots': shots,'entryPoint':'Qrng__SampleQuantumRandomNumberGenerator'} - input_params = {'arguments':[], 'targetCapability': 'AdaptiveExecution', 'shots': 250,'entryPoint':'Qrng__SampleQuantumRandomNumberGenerator'} - # <<<<< + # >>>>> Get more of these parameters from the command line >>>>> + # >>>>> + input_params = {'arguments':[], 'targetCapability': target_capability, 'shots': shots,'entryPoint': entry_point} job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) - job_details = {'container_uri': container_uri, # >>>>> See vendored_sdks\azure_quantum\models\_models_py3.py, line 132 + job_details = {'container_uri': container_uri, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 'input_data_format': job_input_format, 'output_data_format': job_output_format, 'inputParams': input_params, @@ -383,12 +337,6 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location # Submit the job job = client.create(job_id, job_details) - # >>>>> - # # job = client.get(job_id) - # knack_logger.warning(f"Job Status: {job.status}") - # knack_logger.warning(f"Job ID: {job_id}") - # <<<<< - # >>>>> Do we need any logic based on status here? <<<<< return job From 76feb44dbaf8b522c442cfec84ed58e93cee9c2f Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 1 Nov 2022 14:05:04 -0700 Subject: [PATCH 18/65] Remove commented-out code and unused parameters --- .../azext_quantum/tests/latest/test_quantum_jobs.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index 3c8d1d009f9..2e5f9bb00ee 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -237,3 +237,14 @@ def test_validate_max_poll_wait_secs(self): assert False except InvalidArgumentValueError as e: assert str(e) == "--max-poll-wait-secs parameter is not valid: foobar" + + def test_submit_qir(self) + # set current workspace: + self.cmd(f'az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace()} -l {get_test_workspace_location()}') + + # submit a QIR job + self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\source_for_build_test\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") + + + + From 599ac9ee9439eaee277b3fd91546e772a1c56611 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 2 Nov 2022 18:16:56 -0700 Subject: [PATCH 19/65] Add storage account lookup --- src/quantum/azext_quantum/operations/job.py | 9 ++++++--- .../tests/latest/input_data/Qrng.bc | Bin 0 -> 1728 bytes .../tests/latest/test_quantum_jobs.py | 14 +++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index a114dd4c9bf..5f88d5ea001 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,6 +18,7 @@ from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo +# from .workspace import WorkspaceInfo, get from .target import TargetInfo # from ..vendored_sdks.azure_quantum import QuantumClient @@ -286,9 +287,11 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location # Upload the QIR file to the workspace's storage account if storage is None: - # >>>>> Look up the storage account name here <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< - storage = "vwjonesstorage2" - # <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< + from .workspace import get as ws_get + ws = ws_get(cmd) + storage = ws.storage_account.split('/')[-1] + # knack_logger.warning(f"storage = {storage}") + # return connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] diff --git a/src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc b/src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc new file mode 100644 index 0000000000000000000000000000000000000000..6fb4ee7729d450c6cd20bd49548ee4b40c4f545b GIT binary patch literal 1728 zcmaJ>e@Giw9Diptm)7i(*3c&NF1>3~CSBKEV``Hn0b{JQU0I`DHwPWbCArMD8qYJ) z=zfrx$XV(iX(ucN2MNfa|5~Aag%!4U(T&oLJ-GLM z-|zc;-+jK{_x-*G$IQx66#x|g0FRv3pM3W#|3`mJo~~?(oI;?Dk^^uSE-K3?PzLoq z@I#}zEB0*p38~UxzKX=<2P$M5ZTV$SM0LEZ;c8{WxYD39$<%M`G_(#kbMut0akns{ zv|larWo0*1q@!t={2DQ|#?=RF4knI#IC1U@c{2;oy+i__fzq(Qc?aof0@Ta;q>4HK zC(TRpq49*f)pw56vxA@-p^;Q%=wwCK*aQ}7Bt1B^=QyZ?>uWktp-VL`$RbLI_kjMw zwOca4H-+PQ98o6`>xu7V`4&P3|Iwm`aX?u;mj4qDA+1`DYKzo9cY(M&ORS5bgA))V zE~*9rc#)FtkY5Kz=qtK!jYXhtP21lofwoO4gdRUQbi^6i)Z;p0G~o@tt^7i z7jVA{u?;&+@ytj=1nm!_J;`qQJ)n4?#2!bmT6u$ZZkD){#{G0f2^Oo)No-k%ZA4P&qk-!SHB0wuvH?d78R;!#RRw#UlBIX#apT1<7 zj#(BR=1GZlI%bVaEV)fpuN(cK9X-}A@NkX@TteX7Xm1VL`=kOM+ZPdBGND^7@JXRR z89nrH6MLA)ew)EIXo)AA#*1k@SDKd@e1XE}qr?Iu{UPBnXC3BbX`afMMjfVMiDfkN zD*WlwLCg0N%S1+g`@F!l2|O1IwxeOU5L64nl%TnDM)43ResyBS1h!hQD3I6&jDoBo zmS?qdcI{mXhsCg*$BPBx7ewnt^rTwZ+2Tr2?@62{dag6EWLltU8`CjX2D?jCE?(oXx-(t-0pOZW#($ zb;AU<37Q{oVHQ;RIJg8HB#}r6ALJ@RT_ipqrCLzJXUmKPiWmw8w@@dC6)?% zHz?vBMa)wKyuo#9pP&59GVQQUNz9`$bFOU~-aZU=0P<`W`Z(A$*I{2!u*NEP@-^`8 z(1A8C3Go@2CG%ot@E(3E{ldCkEG>BKR!;U9SKZisCrq`XC?;HS--$h*h(yu;no=c% z1sH{xhc<33W12)P<1yQ4rtBgtDtx(sFOztY5$E-&c8%~{7| zmN8fW5?d-}g~gD_h#kU^0PKUZs@#4ELQ8L${$i@sWIAa%7<4=JI%x%zGx+SV9f^?Y z`X<`r2Bb{-$u8ygmVRzHDsG)>qDRy!ARDxwE!Rn<(2Ld}=|cV1`}w)D9(5|eQ88b- z8{>_yRKeesMmGt71g;F2a(^65{nO0v!MF7^wC|RTa-y+?54`Vkonbn;4z?x41cIT? zRwm%<>U=ZQ>0$ZT*#OHk!7kqA>fYLQx%i-{c+Ll1Oh-qTmkF}}zsc}C)Bm3kp6y_n zo@d>=&-b`o?Jk$6%lE8H$=vxbv&e*JdqN#SSBUe8M0nQE@@&A%y1ZSXK#6E6rY+Xn zSf2HE@jh2qD9D9^M`{n#hiTGx%u`oq_S7=9bgl8I*YEXt41OPLVElD{qlsaR9<$M8 KJnDlf1AhUIzB3H~ literal 0 HcmV?d00001 diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index 2e5f9bb00ee..84ae1e0dd35 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -238,13 +238,9 @@ def test_validate_max_poll_wait_secs(self): except InvalidArgumentValueError as e: assert str(e) == "--max-poll-wait-secs parameter is not valid: foobar" - def test_submit_qir(self) - # set current workspace: - self.cmd(f'az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace()} -l {get_test_workspace_location()}') - - # submit a QIR job - self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\source_for_build_test\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") - - - + # def test_submit_qir(self) + # # set current workspace: + # self.cmd(f'az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace()} -l {get_test_workspace_location()}') + # # submit a QIR job + # job_submit_results = self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") From 2666aaa0ac9420ccf624efa48581cd08a09b2162 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 3 Nov 2022 12:14:05 -0700 Subject: [PATCH 20/65] Add parameter defaults and consolidate test input files --- src/quantum/azext_quantum/operations/job.py | 64 ++++--------------- .../Program.qs | 0 .../QuantumRNG.csproj | 0 .../tests/latest/test_quantum_jobs.py | 19 +++--- 4 files changed, 23 insertions(+), 60 deletions(-) rename src/quantum/azext_quantum/tests/latest/{source_for_build_test => input_data}/Program.qs (100%) rename src/quantum/azext_quantum/tests/latest/{source_for_build_test => input_data}/QuantumRNG.csproj (100%) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 5f88d5ea001..d7bb8193641 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,65 +18,23 @@ from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo -# from .workspace import WorkspaceInfo, get from .target import TargetInfo -# from ..vendored_sdks.azure_quantum import QuantumClient -# from ..vendored_sdks.azure_quantum.operations import ( -# JobsOperations, -# StorageOperations, -# QuotasOperations -# ) from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python # >>>>> >>>>> Import these functions from qdk-python and remove the local copy of storage.py <<<<< <<<<< -# from .storage import create_container, create_container_using_client, get_container_uri, ContainerClient, upload_blob -from .storage import create_container, upload_blob +# from .storage import create_container, upload_blob +from azure.quantum.storage import create_container, upload_blob MINIMUM_MAX_POLL_WAIT_SECS = 1 JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" +DEFAULT_SHOTS = 500 logger = logging.getLogger(__name__) knack_logger = knack.log.get_logger(__name__) -# >>>>> >>>>> -# >>>>> Code from top of qdk-python\azure-quantum\azure\quantum\workspace.py -# >>>>> qdk-python AutoREST client imports -# >>>>> -# from typing import Any, Dict, Iterable, List, Optional, TYPE_CHECKING, Tuple, Union -# from deprecated import deprecated - -# # Temporarily replacing the DefaultAzureCredential with -# # a custom _DefaultAzureCredential -# # from azure.identity import DefaultAzureCredential -# from azure.quantum._authentication import _DefaultAzureCredential - -# from azure.quantum._client import QuantumClient -# from azure.quantum._client.operations import ( -# JobsOperations, -# StorageOperations, -# QuotasOperations -# ) -# from azure.quantum._client.models import BlobDetails, JobStatus -# from azure.quantum import Job -# from azure.quantum.storage import create_container_using_client, get_container_uri, ContainerClient - -# from .version import __version__ - -# if TYPE_CHECKING: -# from azure.quantum._client.models import TargetStatus -# from azure.quantum.target import Target - -# logger = logging.getLogger(__name__) - -# __all__ = ["Workspace"] - -# DEFAULT_CONTAINER_NAME_FORMAT = "job-{job_id}" -# USER_AGENT_APPID_ENV_VAR_NAME = "AZURE_QUANTUM_PYTHON_APPID" -# <<<<< <<<<< - def list(cmd, resource_group_name, workspace_name, location): """ @@ -242,12 +200,13 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar # Submit QIR return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, - # job_input_source, job_input_format, job_output_format, job_input_file, job_input_format, job_output_format, entry_point) - + # # Add elifs here to handle new job_input_format values + # + # >>>>> Do we want to allow this? elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": pass # Fall through, same as when job_input_format is None @@ -271,7 +230,6 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location if job_output_format is None: job_output_format = "microsoft.quantum-results.v1" - # if job_input_source is None: if job_input_file is None: # If no pathname was specified, look for a QIR bitcode file in the current folder path = os.path.abspath(os.curdir) @@ -280,8 +238,6 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location # job_input_source = os.path.join(path, file_name) job_input_file = os.path.join(path, file_name) break - # if job_input_source is None: - # raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) if job_input_file is None: raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) @@ -312,8 +268,9 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) - # Convert the --shots string to an integer - if shots is not None: + if shots is None: + shots = DEFAULT_SHOTS + else: error_msg = "--shots value is not valid." recommendation = "Enter a positive integer." try: @@ -323,6 +280,9 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location except: raise InvalidArgumentValueError(error_msg, recommendation) + if target_capability is None: + target_capability = "AdaptiveExecution" + # >>>>> # >>>>> Get more of these parameters from the command line >>>>> # >>>>> diff --git a/src/quantum/azext_quantum/tests/latest/source_for_build_test/Program.qs b/src/quantum/azext_quantum/tests/latest/input_data/Program.qs similarity index 100% rename from src/quantum/azext_quantum/tests/latest/source_for_build_test/Program.qs rename to src/quantum/azext_quantum/tests/latest/input_data/Program.qs diff --git a/src/quantum/azext_quantum/tests/latest/source_for_build_test/QuantumRNG.csproj b/src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj similarity index 100% rename from src/quantum/azext_quantum/tests/latest/source_for_build_test/QuantumRNG.csproj rename to src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index 84ae1e0dd35..ed76252138a 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -44,16 +44,16 @@ def test_job_errors(self): issue_cmd_with_param_missing(self, "az quantum job wait", "az quantum job wait -g MyResourceGroup -w MyWorkspace -l MyLocation -j yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy --max-poll-wait-secs 60 -o table\nWait for completion of a job, check at 60 second intervals.") def test_build(self): - result = build(self, target_id='ionq.simulator', project='src\\quantum\\azext_quantum\\tests\\latest\\source_for_build_test\\QuantumRNG.csproj', target_capability='BasicQuantumFunctionality') + result = build(self, target_id='ionq.simulator', project='src\\quantum\\azext_quantum\\tests\\latest\\input_data\\QuantumRNG.csproj', target_capability='BasicQuantumFunctionality') assert result == {'result': 'ok'} - self.testfile = open(os.path.join(os.path.dirname(__file__), 'source_for_build_test/obj/qsharp/config/qsc.rsp')) + self.testfile = open(os.path.join(os.path.dirname(__file__), 'input_data/obj/qsharp/config/qsc.rsp')) self.testdata = self.testfile.read() self.assertIn('TargetCapability:BasicQuantumFunctionality', self.testdata) self.testfile.close() try: - build(self, target_id='ionq.simulator', project='src\\quantum\\azext_quantum\\tests\\latest\\source_for_build_test\\QuantumRNG.csproj', target_capability='BogusQuantumFunctionality') + build(self, target_id='ionq.simulator', project='src\\quantum\\azext_quantum\\tests\\latest\\input_data\\QuantumRNG.csproj', target_capability='BogusQuantumFunctionality') assert False except AzureInternalError as e: assert str(e) == "Failed to compile program." @@ -238,9 +238,12 @@ def test_validate_max_poll_wait_secs(self): except InvalidArgumentValueError as e: assert str(e) == "--max-poll-wait-secs parameter is not valid: foobar" - # def test_submit_qir(self) - # # set current workspace: - # self.cmd(f'az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace()} -l {get_test_workspace_location()}') + @live_only() + def test_submit_qir(self) + # set current workspace: + # self.cmd(f"az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace_qci()} -l {get_test_workspace_location()}") + self.cmd("az quantum target set -t qci.simulator") - # # submit a QIR job - # job_submit_results = self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") + # submit a QIR job + # job_submit_results = self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") + # >>>>> Validate results <<<<< From 01021fa351156236980fadb63c01418e81c26a1d Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 3 Nov 2022 18:07:21 -0700 Subject: [PATCH 21/65] Fixed style-rule violations. Worked on tests. --- src/quantum/azext_quantum/operations/job.py | 51 +-- .../azext_quantum/operations/storage.py | 383 ------------------ .../tests/latest/test_quantum_jobs.py | 4 +- .../tests/latest/test_quantum_workspace.py | 2 +- 4 files changed, 18 insertions(+), 422 deletions(-) delete mode 100644 src/quantum/azext_quantum/operations/storage.py diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index d7bb8193641..5499242e80f 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -# pylint: disable=redefined-builtin,bare-except,inconsistent-return-statements +# pylint: disable=line-too-long,redefined-builtin,bare-except,inconsistent-return-statements import logging import json @@ -15,18 +15,11 @@ from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) - +from azure.quantum.storage import create_container, upload_blob from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo -from ..vendored_sdks.azure_quantum.models import BlobDetails, JobStatus -from ..vendored_sdks.azure_quantum.operations._jobs_operations import JobsOperations # Was "import Job" in qdk-python - -# >>>>> >>>>> Import these functions from qdk-python and remove the local copy of storage.py <<<<< <<<<< -# from .storage import create_container, upload_blob -from azure.quantum.storage import create_container, upload_blob - MINIMUM_MAX_POLL_WAIT_SECS = 1 JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" @@ -176,7 +169,6 @@ def _set_cli_version(): # before support for the --user-agent parameter is added. We'll rely on the environment # variable before the stand alone executable submits to the service. try: - import os from .._client_factory import get_appid os.environ["USER_AGENT"] = get_appid() except: @@ -189,9 +181,7 @@ def _has_completed(job): def submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, - # job_input_source=None, job_input_format=None, job_output_format=None, - job_input_file=None, job_input_format=None, job_output_format=None, - entry_point=None): + job_input_file=None, job_input_format=None, job_output_format=None, entry_point=None): """ Submit a quantum program to run on Azure Quantum. """ @@ -199,14 +189,13 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar if job_input_format.lower() == "qir.v1": # Submit QIR return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, - entry_point) + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point) # # Add elifs here to handle new job_input_format values # - # >>>>> Do we want to allow this? + # >>>>> Do we want to provide this? elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": pass # Fall through, same as when job_input_format is None @@ -219,10 +208,8 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - # job_input_source, job_input_format, job_output_format, - job_input_file, job_input_format, job_output_format, - entry_point): + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point): """ Submit QIR bitcode for a quantum program or circuit to run on Azure Quantum. @@ -281,12 +268,12 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location raise InvalidArgumentValueError(error_msg, recommendation) if target_capability is None: - target_capability = "AdaptiveExecution" + target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? # >>>>> - # >>>>> Get more of these parameters from the command line >>>>> + # >>>>> TODO: Get more parameters from the command line <<<<< # >>>>> - input_params = {'arguments':[], 'targetCapability': target_capability, 'shots': shots,'entryPoint': entry_point} + input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) @@ -369,8 +356,8 @@ def output(cmd, job_id, resource_group_name, workspace_name, location): Get the results of running a Q# job. """ import tempfile - import json - import os + # import json + # import os from azure.cli.command_modules.storage._client_factory import blob_data_service_factory path = os.path.join(tempfile.gettempdir(), job_id) @@ -481,21 +468,13 @@ def job_show(cmd, job_id, resource_group_name, workspace_name, location): def run(cmd, program_args, resource_group_name, workspace_name, location, target_id, project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source=None, job_input_format=None, job_output_format=None, - # Guen's proposed param names: - qir_payload=None, qir_endpoint=None, qir_param=None): + job_input_file=None, job_input_format=None, job_output_format=None, entry_point=None): """ Submit a job to run on Azure Quantum, and wait for the result. """ job = submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability, - # >>>>> TODO: Finalize these names <<<<< - # Peter's proposed param names: - job_input_source, job_input_format, job_output_format, - # Guen's proposed param names: - qir_payload, qir_endpoint, qir_param) + job_input_file, job_input_format, job_output_format, entry_point) logger.warning("Job id: %s", job.id) logger.debug(job) diff --git a/src/quantum/azext_quantum/operations/storage.py b/src/quantum/azext_quantum/operations/storage.py deleted file mode 100644 index 23eda0a0673..00000000000 --- a/src/quantum/azext_quantum/operations/storage.py +++ /dev/null @@ -1,383 +0,0 @@ -## -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. -## -import logging -from typing import Any, Dict -from azure.core import exceptions -from azure.storage.blob import ( - BlobServiceClient, - ContainerClient, - BlobClient, - BlobSasPermissions, - ContentSettings, - generate_blob_sas, - generate_container_sas, - BlobType, -) -from datetime import datetime, timedelta -from enum import Enum - -logger = logging.getLogger(__name__) - - -def create_container( - connection_string: str, container_name: str -) -> ContainerClient: - """ - Creates and initialize a container; returns the client needed to access it. - """ - blob_service_client = BlobServiceClient.from_connection_string( - connection_string - ) - logger.info( - f'{"Initializing storage client for account:"}' - + f"{blob_service_client.account_name}" - ) - - container_client = blob_service_client.get_container_client(container_name) - create_container_using_client(container_client) - return container_client - - -def create_container_using_client(container_client: ContainerClient): - """ - Creates the container if it doesn't already exist. - """ - if not container_client.exists(): - logger.debug( - f'{" - uploading to **new** container:"}' - f"{container_client.container_name}" - ) - container_client.create_container() - - -def get_container_uri(connection_string: str, container_name: str) -> str: - """ - Creates and initialize a container; - returns a URI with a SAS read/write token to access it. - """ - container = create_container(connection_string, container_name) - logger.info( - f'{"Creating SAS token for container"}' - + f"'{container_name}' on account: '{container.account_name}'" - ) - - sas_token = generate_container_sas( - container.account_name, - container.container_name, - account_key=container.credential.account_key, - permission=BlobSasPermissions( - read=True, add=True, write=True, create=True - ), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - uri = container.url + "?" + sas_token - logger.debug(f" - container url: '{uri}'.") - return uri - - -def upload_blob( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Uploading blob '{blob_name}'" - + f"to container '{container.container_name}'" - + f"on account: '{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - - blob = container.get_blob_client(blob_name) - - blob.upload_blob(data, content_settings=content_settings) - logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") - - if return_sas_token: - uri = get_blob_uri_with_sas_token(blob) - else: - uri = remove_sas_token(blob.url) - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -def append_blob( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, - metadata: Dict[str, str] = None, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Appending data to blob '{blob_name}'" - + f"in container '{container.container_name}'" - + f"on account: '{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - blob = container.get_blob_client(blob_name) - try: - props = blob.get_blob_properties() - if props.blob_type != BlobType.AppendBlob: - raise Exception("blob must be an append blob") - except exceptions.ResourceNotFoundError: - props = blob.create_append_blob( - content_settings=content_settings, metadata=metadata - ) - - blob.append_block(data, len(data)) - logger.debug(f" - blob '{blob_name}' appended. generating sas token.") - - if return_sas_token: - uri = get_blob_uri_with_sas_token(blob) - else: - uri = remove_sas_token(blob.url) - - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -def get_blob_uri_with_sas_token(blob: BlobClient): - """Returns a URI for the given blob that contains a SAS Token""" - sas_token = generate_blob_sas( - blob.account_name, - blob.container_name, - blob.blob_name, - account_key=blob.credential.account_key, - permission=BlobSasPermissions(read=True), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - return blob.url + "?" + sas_token - - -def download_blob(blob_url: str) -> Any: - """ - Downloads the given blob from the container. - """ - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Downloading blob '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}'" - + f"on account: '{blob_client.account_name}'" - ) - - response = blob_client.download_blob().readall() - logger.debug(response) - - return response - - -def download_blob_properties(blob_url: str) -> Dict[str, str]: - """Downloads the blob properties from Azure for the given blob URI""" - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Downloading blob properties '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}'" - + f"on account: '{blob_client.account_name}'" - ) - - response = blob_client.get_blob_properties() - logger.debug(response) - - return response - - -def download_blob_metadata(blob_url: str) -> Dict[str, str]: - """Downloads the blob metadata from the - blob properties in Azure for the given blob URI""" - return download_blob_properties(blob_url).metadata - - -def set_blob_metadata(blob_url: str, metadata: Dict[str, str]): - """Sets the provided dictionary as the metadata on the Azure blob""" - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Setting blob properties '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}' on account:" - + f"'{blob_client.account_name}'" - ) - return blob_client.set_blob_metadata(metadata=metadata) - - -def remove_sas_token(sas_uri: str) -> str: - """Removes the SAS Token from the given URI if it contains one""" - index = sas_uri.find("?") - if index != -1: - sas_uri = sas_uri[0:index] - - return sas_uri - - -def init_blob_for_streaming_upload( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Streaming blob '{blob_name}'" - + f"to container '{container.container_name}' on account:" - + f"'{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - blob = container.get_blob_client(blob_name) - blob.stage_block() - blob.commit_block_list() - blob.upload_blob(data, content_settings=content_settings) - logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") - - if return_sas_token: - sas_token = generate_blob_sas( - blob.account_name, - blob.container_name, - blob.blob_name, - account_key=blob.credential.account_key, - permission=BlobSasPermissions(read=True), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - uri = blob.url + "?" + sas_token - else: - uri = remove_sas_token(blob.url) - - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -class StreamedBlobState(str, Enum): - not_initialized = 0 - uploading = 1 - committed = 2 - - -class StreamedBlob: - """Class that provides a state machine for writing - blobs using the Azure Block Blob API - - Internally implements a state machine for uploading blob data. - To use, start calling `upload_data()` - to add data blocks. Each call to `upload_data()` - will synchronously upload an individual block to Azure. - Once all blocks have been added, call `commit()` - to commit the blocks and make the blob available/readable. - - :param container: The container client that the blob will be uploaded to - :param blob_name: The name of the blob - (including optional path) within the blob container - :param content_type: The HTTP content type to apply to the blob metadata - :param content_encoding: The HTTP - content encoding to apply to the blob metadata - """ - - def __init__( - self, - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - ): - self.container = container - self.blob_name = blob_name - self.content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - self.state = StreamedBlobState.not_initialized - self.blob = container.get_blob_client(blob_name) - self.blocks = [] - - def upload_data(self, data): - """Synchronously uploads a block to the given block blob in Azure - - :param data: The data to be uploaded as a block. - :type data: Union[Iterable[AnyStr], IO[AnyStr]] - """ - if self.state == StreamedBlobState.not_initialized: - create_container_using_client(self.container) - logger.info( - f"Streaming blob '{self.blob_name}' to container" - + f"'{self.container.container_name}'" - + f"on account: '{self.container.account_name}'" - ) - self.initialized = True - - self.state = StreamedBlobState.uploading - id = self._get_next_block_id() - logger.debug(f"Uploading block '{id}' to {self.blob_name}") - self.blob.stage_block(id, data, length=len(data)) - self.blocks.append(id) - - def commit(self, metadata: Dict[str, str] = None): - """Synchronously commits all previously - uploaded blobs to the block blob - - :param metadata: Optional dictionary of - metadata to be applied to the block blob - """ - if self.state == StreamedBlobState.not_initialized: - raise Exception("StreamedBlob cannot commit before uploading data") - elif self.state == StreamedBlobState.committed: - raise Exception("StreamedBlob is already committed") - - logger.debug(f"Committing {len(self.blocks)} blocks {self.blob_name}") - self.blob.commit_block_list( - self.blocks, - content_settings=self.content_settings, - metadata=metadata, - ) - self.state = StreamedBlobState.committed - logger.debug(f"Committed {self.blob_name}") - - def getUri(self, with_sas_token: bool = False): - """Gets the full Azure Storage URI for the - uploaded blob after it has been committed""" - if self.state != StreamedBlobState.committed: - raise Exception("Can only retrieve sas token for committed blob") - if with_sas_token: - return get_blob_uri_with_sas_token(self.blob) - - return remove_sas_token(self.blob.url) - - def _get_next_block_id(self): - return f"{len(self.blocks):10}" diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index ed76252138a..a26b26601a6 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -239,11 +239,11 @@ def test_validate_max_poll_wait_secs(self): assert str(e) == "--max-poll-wait-secs parameter is not valid: foobar" @live_only() - def test_submit_qir(self) + def test_submit_qir(self): # set current workspace: # self.cmd(f"az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace_qci()} -l {get_test_workspace_location()}") self.cmd("az quantum target set -t qci.simulator") # submit a QIR job - # job_submit_results = self.cmd("az quantum job submit --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") + # results = self.cmd("az quantum job run --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") # >>>>> Validate results <<<<< diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_workspace.py b/src/quantum/azext_quantum/tests/latest/test_quantum_workspace.py index ed65adfb7c4..e34c6dc15ba 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_workspace.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_workspace.py @@ -155,7 +155,7 @@ def test_workspace_create_destroy(self): # @pytest.fixture(autouse=True) # def _pass_fixtures(self, capsys): # self.capsys = capsys - # # See "TODO" in issue_cmd_with_param_missing un utils.py + # # See "TODO" in issue_cmd_with_param_missing in utils.py @live_only() def test_workspace_errors(self): From b08b75a8f4015eaccc940bf7e3b63e73afe5b109 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 4 Nov 2022 10:49:56 -0700 Subject: [PATCH 22/65] Add azure-quantum to DEPENDENCIES --- src/quantum/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 6ec07847d77..068eb291999 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -34,6 +34,7 @@ ] DEPENDENCIES = [ + 'azure-quantum~=0.27.238334' ] with open('README.rst', 'r', encoding='utf-8') as f: From c571a97fbbceea5b253ef2ceb33de53f89b5855d Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 8 Nov 2022 14:29:28 -0800 Subject: [PATCH 23/65] Temporarily comment out code in QIR job submit test --- src/quantum/azext_quantum/operations/job.py | 3 +- .../tests/latest/test_quantum_jobs.py | 53 ++++++++++++++++--- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 5499242e80f..219bd6c86db 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -187,10 +187,10 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ if job_input_format is not None: if job_input_format.lower() == "qir.v1": - # Submit QIR return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point) + # # Add elifs here to handle new job_input_format values # @@ -244,7 +244,6 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location content_type = "application/x-qir.v1" # This is what a Q# executable sets for the inputData blob, but "qir.v1" is shown in the inputParams content_encoding = None return_sas_token = False - # with open(job_input_source, "rb") as qir_file: with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index a26b26601a6..bf9280ad59d 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -12,10 +12,10 @@ from azure.cli.testsdk import ScenarioTest from azure.cli.core.azclierror import InvalidArgumentValueError, AzureInternalError -from .utils import get_test_subscription_id, get_test_resource_group, get_test_workspace, get_test_workspace_location, issue_cmd_with_param_missing +from .utils import get_test_subscription_id, get_test_resource_group, get_test_workspace, get_test_workspace_location, issue_cmd_with_param_missing, get_test_workspace_storage, get_test_workspace_random_name from ..._client_factory import _get_data_credentials from ...commands import transform_output -from ...operations.workspace import WorkspaceInfo +from ...operations.workspace import WorkspaceInfo, DEPLOYMENT_NAME_PREFIX from ...operations.target import TargetInfo from ...operations.job import _generate_submit_args, _parse_blob_url, _validate_max_poll_wait_secs, build @@ -240,10 +240,49 @@ def test_validate_max_poll_wait_secs(self): @live_only() def test_submit_qir(self): - # set current workspace: - # self.cmd(f"az quantum workspace set -g {get_test_resource_group()} -w {get_test_workspace_qci()} -l {get_test_workspace_location()}") + test_location = get_test_workspace_location() + test_resource_group = get_test_resource_group() + # test_workspace_temp = get_test_workspace_random_name() + test_workspace_temp = "e2e-test-v-wjones-local" # <<<<< Temporarily used for local debugging <<<<< + # test_qir-provider_sku_list = "qci/qci-freepreview" + test_qir_provider_sku_list = "qci/qci-freepreview, Microsoft/DZH3178M639F" # <<<<< Microsoft SKU added here because it's also an auto-add provider, speeds up workspace creation <<<<< + # <<<<< # <<<<< Remove Microsoft SKU after Task 46910 is implemented <<<<< + test_storage_account = get_test_workspace_storage() + test_bitcode_pathname = "src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc" + + # # Create a workspace + # self.cmd(f'az quantum workspace create -g {test_resource_group} -w {test_workspace_temp} -l {test_location} -a {test_storage_account} -r "{test_qir_provider_sku_list}" -o json', checks=[ + # self.check("name", DEPLOYMENT_NAME_PREFIX + test_workspace_temp), + # ]) + # <<<<< Temporarily commented-out to speed up the local tests during debugging <<<<< + + # Run a QIR job + self.cmd(f"az quantum workspace set -g {test_resource_group} -w {test_workspace_temp} -l {test_location}") self.cmd("az quantum target set -t qci.simulator") - # submit a QIR job - # results = self.cmd("az quantum job run --shots 100 --job-input-format qir.v1 --job-input-file 'src\\quantum\\azext_quantum\\tests\\latest\\input_data\\Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator") - # >>>>> Validate results <<<<< + # results = self.cmd("az quantum run --shots 100 --job-input-format qir.v1 --job-input-file src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator -o json") + # self.assertIn("Histogram", results) + + # self.cmd(f"az quantum run --shots 99 --job-input-format qir.v1 --job-input-file {test_bitcode_pathname} --entry-point Qrng__SampleQuantumRandomNumberGenerator") + + # >>>>> Trying to suppress logging because "azdev test" tries to log the bitcode file data as utf-8 unicode and crashes >>>> + import logging + # logger = logging.getLogger(__name__) + logger = logging.getLogger() + + # logger.disable() + # logger.disabled() + # logger.shutdown() + # logger.manager.disable() + # logger.setLevel(logging.CRITICAL + 1) + # logger.disabled == True + logger.addFilter(lambda record: False) + + #results = self.cmd(f"az quantum run --shots 99 --job-input-format qir.v1 --job-input-file {test_bitcode_pathname} --entry-point Qrng__SampleQuantumRandomNumberGenerator").get_output_in_json() + + # # Delete the workspace + # self.cmd(f'az quantum workspace delete -g {test_resource_group} -w {test_workspace_temp} -o json', checks=[ + # self.check("name", test_workspace_temp), + # self.check("provisioningState", "Deleting") + # ]) + # <<<<< Temporarily commented-out during local debugging: Re-use the workspace for local tests <<<<< From e067a0acf8fc03bcff140383b26511ea91dbcbc5 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 8 Nov 2022 15:17:35 -0800 Subject: [PATCH 24/65] Delete whitespace that Flake8 doesn't like --- src/quantum/azext_quantum/operations/job.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 219bd6c86db..31edc690a85 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -190,7 +190,10 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point) - + + # elif job_input_format.lower() == "microsoft.qio.v2": + # return _submit_qio(cmd, program_args, resource_group_name, workspace_name, location, target_id,... + # # Add elifs here to handle new job_input_format values # From 9276dabf09bb15e8151b332148f1b3cf07fb1f2c Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 9 Nov 2022 18:21:24 -0800 Subject: [PATCH 25/65] Add code to submit QIO jobs --- src/quantum/azext_quantum/operations/job.py | 147 +++++++++++++------- 1 file changed, 94 insertions(+), 53 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 31edc690a85..3f086a62079 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -23,8 +23,14 @@ MINIMUM_MAX_POLL_WAIT_SECS = 1 JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" +JOB_TYPE_NOT_VALID_MSG = "Internal error: Job type not recognized." DEFAULT_SHOTS = 500 +# Job types +QSHARP_JOB = 0 +QIO_JOB = 1 +QIR_JOB = 2 + logger = logging.getLogger(__name__) knack_logger = knack.log.get_logger(__name__) @@ -185,70 +191,98 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ - if job_input_format is not None: - if job_input_format.lower() == "qir.v1": - return _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, entry_point) - - # elif job_input_format.lower() == "microsoft.qio.v2": - # return _submit_qio(cmd, program_args, resource_group_name, workspace_name, location, target_id,... - - # - # Add elifs here to handle new job_input_format values - # + # Identify the type of job being submitted + if job_input_format is None: + job_type = QSHARP_JOB + elif job_input_format.lower() == "microsoft.qio.v2": + job_type = QIO_JOB + elif job_input_format.lower() == "qir.v1": + job_type = QIR_JOB + else: + raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) - # >>>>> Do we want to provide this? - elif job_input_format.lower() == "q#" or job_input_format.lower() == "qsharp": - pass # Fall through, same as when job_input_format is None + if job_type == QIO_JOB: + return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point) - else: - raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) + if job_type == QIR_JOB: + return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point) - # Submit a Q# project. (Do it the old way, for now.) - return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project, job_name, shots, storage, no_build, job_params, target_capability) + if job_type == QSHARP_JOB: + return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability) -def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, entry_point): +def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point): """ - Submit QIR bitcode for a quantum program or circuit to run on Azure Quantum. + Submit QIO problem JSON or QIR bitcode to run on Azure Quantum. """ if job_output_format is None: - job_output_format = "microsoft.quantum-results.v1" + if job_type == QIO_JOB: + job_output_format = "microsoft.qio-results.v2" + elif job_type == QIR_JOB: + job_output_format = "microsoft.quantum-results.v1" + else: + raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) if job_input_file is None: - # If no pathname was specified, look for a QIR bitcode file in the current folder + if job_type == QIO_JOB: + input_file_extension = ".json" + elif job_type == QIR_JOB: + input_file_extension = ".bc" + else: + raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + path = os.path.abspath(os.curdir) for file_name in os.listdir(path): - if file_name.endswith('.bc'): + if file_name.endswith(input_file_extension): # job_input_source = os.path.join(path, file_name) job_input_file = os.path.join(path, file_name) break + if job_input_file is None: - raise RequiredArgumentMissingError("Failed to submit QIR job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) + raise RequiredArgumentMissingError("Failed to submit job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) + + # Prepare for input file upload according to job type + if job_type == QIO_JOB: + container_name_prefix = "cli-qio-job-" + content_type = "application/json" + content_encoding = "gzip" + # content_encoding = None # <<<<< Didn't fix this error: "The archive entry was compressed using an unsupported compression method." + return_sas_token = True # <<<<< The URI from the Jupyter notebook had what looked like a SAS token appended to it + with open(job_input_file, encoding="utf-8") as qio_file: + blob_data = qio_file.read() + elif job_type == QIR_JOB: + container_name_prefix = "cli-qir-job-" + content_type = "application/x-qir.v1" + content_encoding = None + return_sas_token = False + with open(job_input_file, "rb") as qir_file: + blob_data = qir_file.read() + else: + raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) - # Upload the QIR file to the workspace's storage account + # Upload the input file to the workspace's storage account if storage is None: from .workspace import get as ws_get ws = ws_get(cmd) storage = ws.storage_account.split('/')[-1] - # knack_logger.warning(f"storage = {storage}") - # return connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] - container_name = "cli-qir-job-" + str(uuid.uuid4()) + # from datetime import datetime + # container_name = container_name_prefix + datetime().strftime('%y-%m-%d-%H-%M-%S') + str(uuid.uuid4()) + container_name = container_name_prefix + str(uuid.uuid4()) container_client = create_container(connection_string, container_name) blob_name = "inputData" - content_type = "application/x-qir.v1" # This is what a Q# executable sets for the inputData blob, but "qir.v1" is shown in the inputParams - content_encoding = None - return_sas_token = False - with open(job_input_file, "rb") as qir_file: - blob_data = qir_file.read() + # return_sas_token = False + return_sas_token = True blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) # Set the job parameters @@ -257,29 +291,36 @@ def _submit_qir(cmd, program_args, resource_group_name, workspace_name, location ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) - if shots is None: - shots = DEFAULT_SHOTS + if job_type == QIO_JOB: + # >>>>> + # >>>>> TODO: Get parameters from the command line <<<<< + # >>>>> + input_params = {"params": {"timeout": 100}} # <<<<< What other params do we need here? <<<<< <<<<< else: - error_msg = "--shots value is not valid." - recommendation = "Enter a positive integer." - try: - shots = int(shots) - if shots < 1: + if shots is None: + shots = DEFAULT_SHOTS + else: + error_msg = "--shots value is not valid." + recommendation = "Enter a positive integer." + try: + shots = int(shots) + if shots < 1: + raise InvalidArgumentValueError(error_msg, recommendation) + except: raise InvalidArgumentValueError(error_msg, recommendation) - except: - raise InvalidArgumentValueError(error_msg, recommendation) - if target_capability is None: - target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? + if target_capability is None: + target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? - # >>>>> - # >>>>> TODO: Get more parameters from the command line <<<<< - # >>>>> - input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} + # >>>>> + # >>>>> TODO: Get more parameters from the command line <<<<< + # >>>>> + input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) - job_details = {'container_uri': container_uri, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 + job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 + 'container_uri': container_uri, 'input_data_format': job_input_format, 'output_data_format': job_output_format, 'inputParams': input_params, From 5c719855e336ac95d87e33870926a9bb6ece7370 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 10 Nov 2022 17:58:12 -0800 Subject: [PATCH 26/65] Add code from QIO Quickstart notebook --- src/quantum/azext_quantum/operations/job.py | 111 ++++++++++++++++++-- 1 file changed, 105 insertions(+), 6 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 3f086a62079..e9b9df833b0 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -202,9 +202,12 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) if job_type == QIO_JOB: - return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, entry_point) + # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format, entry_point) + return _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format) if job_type == QIR_JOB: return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, @@ -216,6 +219,84 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar project, job_name, shots, storage, no_build, job_params, target_capability) +def _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format): + # >>>>> + knack_logger.warning(">>>>> Submitting QIO job like a notebook <<<<<") + # return + # <<<<< + + # from azure.quantum import Workspace + # workspace = Workspace ( + # subscription_id = , + # resource_group = , + # name = , + # location = + # ) + + from azure.quantum import Workspace + workspace = Workspace ( + subscription_id = "677fc922-91d0-4bf6-9b06-4274d319a0fa", + resource_group = resource_group_name, + name = workspace_name, + location = location + ) + + # >>>>> + knack_logger.warning(">>>>> Cell 1 completed <<<<<") + # return + # <<<<< + + from typing import List + from azure.quantum.optimization import Term + + # >>>>> + knack_logger.warning(">>>>> Cell 2 completed <<<<<") + # return + # <<<<< + + from azure.quantum.optimization import Problem, ProblemType, Term + + # problem = Problem(name="My First Problem", problem_type=ProblemType.ising) + problem = Problem(name=job_name, problem_type=ProblemType.ising) + + # >>>>> + knack_logger.warning(">>>>> Cell 3 completed <<<<<") + # return + # <<<<< + + terms = [ + Term(c=-9, indices=[0]), + Term(c=-3, indices=[1,0]), + Term(c=5, indices=[2,0]), + Term(c=9, indices=[2,1]), + Term(c=2, indices=[3,0]), + Term(c=-4, indices=[3,1]), + Term(c=4, indices=[3,2]) + ] + + problem.add_terms(terms=terms) + + # >>>>> + knack_logger.warning(">>>>> Cell 4 completed <<<<<") + # return + # <<<<< + + from azure.quantum.optimization import ParallelTempering + + solver = ParallelTempering(workspace, timeout=100) + + # >>>>> + knack_logger.warning('>>>>> "solver =" statement completed, calling solver.optimize() <<<<<') + # return + # <<<<< + + result = solver.optimize(problem) + # print(result) + return result + + def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): @@ -255,7 +336,8 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name content_type = "application/json" content_encoding = "gzip" # content_encoding = None # <<<<< Didn't fix this error: "The archive entry was compressed using an unsupported compression method." - return_sas_token = True # <<<<< The URI from the Jupyter notebook had what looked like a SAS token appended to it + # return_sas_token = False + return_sas_token = True # <<<<< containerURI from the Jupyter notebook had what looked like a SAS token appended to it with open(job_input_file, encoding="utf-8") as qio_file: blob_data = qio_file.read() elif job_type == QIR_JOB: @@ -282,12 +364,29 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name container_client = create_container(connection_string, container_name) blob_name = "inputData" # return_sas_token = False - return_sas_token = True blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) + # >>>>> + # knack_logger.warning(f">>>>> blob_uri = {blob_uri}") + # return + # <<<<< + # Set the job parameters start_of_blob_name = blob_uri.find(blob_name) - container_uri = blob_uri[0:start_of_blob_name - 1] + if job_type == QIO_JOB: + end_of_blob_name = blob_uri.find("?") + container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] + elif job_type == QIR_JOB: + container_uri = blob_uri[0:start_of_blob_name - 1] + else: + raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + + # >>>>> + # knack_logger.warning(f">>>>> blob_uri = {blob_uri}") + # knack_logger.warning(f">>>>> container_uri = {container_uri}") + # return + # <<<<< + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) From 65290dabc765e4a2d4541f75bdbc86049d616ef1 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 14 Nov 2022 17:59:13 -0800 Subject: [PATCH 27/65] Comment out solver call. Submit QIO like QIR. --- src/quantum/azext_quantum/operations/job.py | 138 +++++++++++--------- 1 file changed, 75 insertions(+), 63 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index e9b9df833b0..b224c7b4f89 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -202,12 +202,12 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) if job_type == QIO_JOB: - # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format, entry_point) - return _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - job_name, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format) + return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point) + # return _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format) if job_type == QIR_JOB: return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, @@ -223,79 +223,72 @@ def _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name job_name, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format): # >>>>> - knack_logger.warning(">>>>> Submitting QIO job like a notebook <<<<<") - # return + knack_logger.warning(">>>>> Submitting QIO job from notebook quickstart article <<<<<") # <<<<< - # from azure.quantum import Workspace - # workspace = Workspace ( - # subscription_id = , - # resource_group = , - # name = , - # location = - # ) + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + if ws_info is None: + raise AzureInternalError("Failed get workspace information. (_submit_qio)") + + # # >>>>> + # knack_logger.warning(f'>>>>> ws_info.subscription = {ws_info.subscription} <<<<<') + # return + # # <<<<< + # Cell 1 from azure.quantum import Workspace workspace = Workspace ( - subscription_id = "677fc922-91d0-4bf6-9b06-4274d319a0fa", + subscription_id = ws_info.subscription, resource_group = resource_group_name, name = workspace_name, location = location ) - # >>>>> - knack_logger.warning(">>>>> Cell 1 completed <<<<<") - # return - # <<<<< + # # Cell 2 + # from typing import List + # from azure.quantum.optimization import Term - from typing import List - from azure.quantum.optimization import Term + # # Cell 3 + # from azure.quantum.optimization import Problem, ProblemType, Term - # >>>>> - knack_logger.warning(">>>>> Cell 2 completed <<<<<") - # return - # <<<<< + # # problem = Problem(name="My First Problem", problem_type=ProblemType.ising) + # problem = Problem(name=job_name, problem_type=ProblemType.ising) - from azure.quantum.optimization import Problem, ProblemType, Term + # # Cell 4 + # terms = [ + # Term(c=-9, indices=[0]), + # Term(c=-3, indices=[1,0]), + # Term(c=5, indices=[2,0]), + # Term(c=9, indices=[2,1]), + # Term(c=2, indices=[3,0]), + # Term(c=-4, indices=[3,1]), + # Term(c=4, indices=[3,2]) + # ] - # problem = Problem(name="My First Problem", problem_type=ProblemType.ising) - problem = Problem(name=job_name, problem_type=ProblemType.ising) + # problem.add_terms(terms=terms) - # >>>>> - knack_logger.warning(">>>>> Cell 3 completed <<<<<") - # return - # <<<<< + # Cell 5 + from azure.quantum.optimization import ParallelTempering - terms = [ - Term(c=-9, indices=[0]), - Term(c=-3, indices=[1,0]), - Term(c=5, indices=[2,0]), - Term(c=9, indices=[2,1]), - Term(c=2, indices=[3,0]), - Term(c=-4, indices=[3,1]), - Term(c=4, indices=[3,2]) - ] + solver = ParallelTempering(workspace, timeout=100) - problem.add_terms(terms=terms) + # # >>>>> + # knack_logger.warning('>>>>> "solver =" statement completed, calling solver.optimize() <<<<<') + # # <<<<< - # >>>>> - knack_logger.warning(">>>>> Cell 4 completed <<<<<") - # return - # <<<<< - - from azure.quantum.optimization import ParallelTempering + # result = solver.optimize(problem) # <<<<< Also takes a URI to an uploaded blob <<<<< + # # print(result) + # return result - solver = ParallelTempering(workspace, timeout=100) # >>>>> - knack_logger.warning('>>>>> "solver =" statement completed, calling solver.optimize() <<<<<') + knack_logger.warning(">>>>> Calling solver.optimize() <<<<<") # return # <<<<< + # return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/job-dc473644-5fa9-11ed-8346-00155d76d204/inputData") # Notebook job + # return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/cli-qio-job-14b6e2af-7e89-41fc-9f14-be77474ba6be/inputData") # Job 7 - result = solver.optimize(problem) - # print(result) - return result - + return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/cli-qio-job-1a61168a-40dc-49ed-b701-7a894f42b178/inputData") # Job 14 def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, @@ -335,10 +328,11 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name container_name_prefix = "cli-qio-job-" content_type = "application/json" content_encoding = "gzip" - # content_encoding = None # <<<<< Didn't fix this error: "The archive entry was compressed using an unsupported compression method." + return_sas_token = True # return_sas_token = False - return_sas_token = True # <<<<< containerURI from the Jupyter notebook had what looked like a SAS token appended to it with open(job_input_file, encoding="utf-8") as qio_file: + # with open(job_input_file) as qio_file: + # with open(job_input_file, "rb") as qio_file: blob_data = qio_file.read() elif job_type == QIR_JOB: container_name_prefix = "cli-qir-job-" @@ -356,14 +350,12 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name ws = ws_get(cmd) storage = ws.storage_account.split('/')[-1] + job_id = str(uuid.uuid4()) + container_name = container_name_prefix + job_id connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] - # from datetime import datetime - # container_name = container_name_prefix + datetime().strftime('%y-%m-%d-%H-%M-%S') + str(uuid.uuid4()) - container_name = container_name_prefix + str(uuid.uuid4()) container_client = create_container(connection_string, container_name) blob_name = "inputData" - # return_sas_token = False blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) # >>>>> @@ -371,6 +363,26 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name # return # <<<<< + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + if ws_info is None: + raise AzureInternalError("Failed get workspace information. (_submit_qio)") + + # >>>>> Try submitting QIO jobs using a solver >>>>> + # if job_type == QIO_JOB: + # from azure.quantum import Workspace + # workspace = Workspace ( + # subscription_id = ws_info.subscription, + # resource_group = resource_group_name, + # name = workspace_name, + # location = location + # ) + + # from azure.quantum.optimization import ParallelTempering + + # solver = ParallelTempering(workspace, timeout=100) + # return solver.optimize(blob_uri) + # <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< << + # Set the job parameters start_of_blob_name = blob_uri.find(blob_name) if job_type == QIO_JOB: @@ -387,7 +399,7 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name # return # <<<<< - ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + # ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) if job_type == QIO_JOB: @@ -416,7 +428,7 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name # >>>>> input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} - job_id = str(uuid.uuid4()) + # job_id = str(uuid.uuid4()) client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 'container_uri': container_uri, From 96590c6cb61d928f5075f6d13c0e6b446e3b59c6 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 15 Nov 2022 13:08:29 -0800 Subject: [PATCH 28/65] Add gzip compression for OIO input --- src/quantum/azext_quantum/operations/job.py | 119 ++------------------ 1 file changed, 11 insertions(+), 108 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index b224c7b4f89..d7a32f092c8 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -10,6 +10,8 @@ import os import uuid import knack.log +import io +import gzip from azure.cli.command_modules.storage.operations.account import show_storage_account_connection_string from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, @@ -205,9 +207,6 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point) - # return _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format) if job_type == QIR_JOB: return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, @@ -219,77 +218,6 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar project, job_name, shots, storage, no_build, job_params, target_capability) -def _submit_qio(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - job_name, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format): - # >>>>> - knack_logger.warning(">>>>> Submitting QIO job from notebook quickstart article <<<<<") - # <<<<< - - ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - if ws_info is None: - raise AzureInternalError("Failed get workspace information. (_submit_qio)") - - # # >>>>> - # knack_logger.warning(f'>>>>> ws_info.subscription = {ws_info.subscription} <<<<<') - # return - # # <<<<< - - # Cell 1 - from azure.quantum import Workspace - workspace = Workspace ( - subscription_id = ws_info.subscription, - resource_group = resource_group_name, - name = workspace_name, - location = location - ) - - # # Cell 2 - # from typing import List - # from azure.quantum.optimization import Term - - # # Cell 3 - # from azure.quantum.optimization import Problem, ProblemType, Term - - # # problem = Problem(name="My First Problem", problem_type=ProblemType.ising) - # problem = Problem(name=job_name, problem_type=ProblemType.ising) - - # # Cell 4 - # terms = [ - # Term(c=-9, indices=[0]), - # Term(c=-3, indices=[1,0]), - # Term(c=5, indices=[2,0]), - # Term(c=9, indices=[2,1]), - # Term(c=2, indices=[3,0]), - # Term(c=-4, indices=[3,1]), - # Term(c=4, indices=[3,2]) - # ] - - # problem.add_terms(terms=terms) - - # Cell 5 - from azure.quantum.optimization import ParallelTempering - - solver = ParallelTempering(workspace, timeout=100) - - # # >>>>> - # knack_logger.warning('>>>>> "solver =" statement completed, calling solver.optimize() <<<<<') - # # <<<<< - - # result = solver.optimize(problem) # <<<<< Also takes a URI to an uploaded blob <<<<< - # # print(result) - # return result - - - # >>>>> - knack_logger.warning(">>>>> Calling solver.optimize() <<<<<") - # return - # <<<<< - # return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/job-dc473644-5fa9-11ed-8346-00155d76d204/inputData") # Notebook job - # return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/cli-qio-job-14b6e2af-7e89-41fc-9f14-be77474ba6be/inputData") # Job 7 - - return solver.optimize("https://vwjonesstorage2.blob.core.windows.net/cli-qio-job-1a61168a-40dc-49ed-b701-7a894f42b178/inputData") # Job 14 - def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): @@ -316,7 +244,6 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name path = os.path.abspath(os.curdir) for file_name in os.listdir(path): if file_name.endswith(input_file_extension): - # job_input_source = os.path.join(path, file_name) job_input_file = os.path.join(path, file_name) break @@ -329,11 +256,14 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name content_type = "application/json" content_encoding = "gzip" return_sas_token = True - # return_sas_token = False with open(job_input_file, encoding="utf-8") as qio_file: - # with open(job_input_file) as qio_file: - # with open(job_input_file, "rb") as qio_file: - blob_data = qio_file.read() + uncompressed_blob_data = qio_file.read() + # Compress the input data (based on to_blob in qdk-python\azure-quantum\azure\quantum\optimization\problem.py) + data = io.BytesIO() + with gzip.GzipFile(fileobj=data, mode="w") as fo: + fo.write(uncompressed_blob_data.encode()) + blob_data = data.getvalue() + elif job_type == QIR_JOB: container_name_prefix = "cli-qir-job-" content_type = "application/x-qir.v1" @@ -341,6 +271,7 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name return_sas_token = False with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() + else: raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) @@ -358,30 +289,9 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name blob_name = "inputData" blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) - # >>>>> - # knack_logger.warning(f">>>>> blob_uri = {blob_uri}") - # return - # <<<<< - ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) if ws_info is None: - raise AzureInternalError("Failed get workspace information. (_submit_qio)") - - # >>>>> Try submitting QIO jobs using a solver >>>>> - # if job_type == QIO_JOB: - # from azure.quantum import Workspace - # workspace = Workspace ( - # subscription_id = ws_info.subscription, - # resource_group = resource_group_name, - # name = workspace_name, - # location = location - # ) - - # from azure.quantum.optimization import ParallelTempering - - # solver = ParallelTempering(workspace, timeout=100) - # return solver.optimize(blob_uri) - # <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< << + raise AzureInternalError("Failed to get workspace information.") # Set the job parameters start_of_blob_name = blob_uri.find(blob_name) @@ -393,13 +303,6 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name else: raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) - # >>>>> - # knack_logger.warning(f">>>>> blob_uri = {blob_uri}") - # knack_logger.warning(f">>>>> container_uri = {container_uri}") - # return - # <<<<< - - # ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) target_info = TargetInfo(cmd, target_id) if job_type == QIO_JOB: From e07577f3b939f669f0d9884914c48943190e5e73 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 15 Nov 2022 15:06:03 -0800 Subject: [PATCH 29/65] Clean up job parameters logic --- src/quantum/azext_quantum/operations/job.py | 37 +++++++++------------ 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index d7a32f092c8..b40ccfb5ede 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -5,13 +5,13 @@ # pylint: disable=line-too-long,redefined-builtin,bare-except,inconsistent-return-statements -import logging +import gzip +import io import json +import logging import os import uuid import knack.log -import io -import gzip from azure.cli.command_modules.storage.operations.account import show_storage_account_connection_string from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, @@ -221,7 +221,6 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): - """ Submit QIO problem JSON or QIR bitcode to run on Azure Quantum. """ @@ -289,28 +288,25 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name blob_name = "inputData" blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) + # Retrieve workspace and target information ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) if ws_info is None: raise AzureInternalError("Failed to get workspace information.") + target_info = TargetInfo(cmd, target_id) + if target_info is None: + raise AzureInternalError("Failed to get target information.") # Set the job parameters start_of_blob_name = blob_uri.find(blob_name) if job_type == QIO_JOB: end_of_blob_name = blob_uri.find("?") container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] - elif job_type == QIR_JOB: - container_uri = blob_uri[0:start_of_blob_name - 1] - else: - raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) - target_info = TargetInfo(cmd, target_id) + # >>>>> TODO: Get more parameters from the command line <<<<< + input_params = {"params": {"timeout": 100}} - if job_type == QIO_JOB: - # >>>>> - # >>>>> TODO: Get parameters from the command line <<<<< - # >>>>> - input_params = {"params": {"timeout": 100}} # <<<<< What other params do we need here? <<<<< <<<<< - else: + elif job_type == QIR_JOB: + container_uri = blob_uri[0:start_of_blob_name - 1] if shots is None: shots = DEFAULT_SHOTS else: @@ -326,12 +322,12 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name if target_capability is None: target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? - # >>>>> # >>>>> TODO: Get more parameters from the command line <<<<< - # >>>>> input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} - # job_id = str(uuid.uuid4()) + else: + raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 'container_uri': container_uri, @@ -342,10 +338,7 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name 'target': target_info.target_id} # Submit the job - job = client.create(job_id, job_details) - - # >>>>> Do we need any logic based on status here? <<<<< - return job + return client.create(job_id, job_details) def _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, From 84b0bd77343aa3b23142b7d950945dee73098b84 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 28 Nov 2022 11:27:17 -0800 Subject: [PATCH 30/65] Remove QIO protobuf code. Add initial pass-through logic. --- src/quantum/azext_quantum/operations/job.py | 128 ++++++++++++++------ 1 file changed, 88 insertions(+), 40 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index b40ccfb5ede..83e0e8d8470 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,20 +18,26 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) from azure.quantum.storage import create_container, upload_blob +# from azure.quantum.optimization.problem import compress_protobuf +from azure.quantum.optimization.problem import Problem from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo MINIMUM_MAX_POLL_WAIT_SECS = 1 -JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/en-us/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" -JOB_TYPE_NOT_VALID_MSG = "Internal error: Job type not recognized." DEFAULT_SHOTS = 500 +QIO_DEFAULT_TIMEOUT = 100 + +ERROR_MSG_MISSING_INPUT_FILE = "The following argument is required: --job-input-file" # NOTE: The Azure CLI core generates a similar error message, but "the" is lowercase and "arguments" is always plural. +ERROR_MSG_MISSING_OUTPUT_FORMAT = "The following argument is required: --job-output-format" +JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" +JOB_TYPE_NOT_VALID_MSG = "Job type not recognized. This is a bug!" # Job types -QSHARP_JOB = 0 QIO_JOB = 1 QIR_JOB = 2 +PASS_THROUGH_JOB = 3 logger = logging.getLogger(__name__) knack_logger = knack.log.get_logger(__name__) @@ -193,52 +199,79 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ - # Identify the type of job being submitted + # # Identify the type of job being submitted + # if job_input_format is None: + # job_type = QSHARP_JOB + # elif job_input_format.lower() == "microsoft.qio.v2": + # job_type = QIO_JOB + # if job_input_file is not None and job_input_file.split(".")[-1].lower() == "pb": + # job_type = QIO_PB_JOB + # elif job_input_format.lower() == "qir.v1": + # job_type = QIR_JOB + # else: + # raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) + # + # if job_type == QIO_JOB: + # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format, entry_point) + # if job_type == QIO_PB_JOB: + # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format, entry_point) + # if job_type == QIR_JOB: + # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format, entry_point) + # if job_type == QSHARP_JOB: + # return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + # project, job_name, shots, storage, no_build, job_params, target_capability) + if job_input_format is None: - job_type = QSHARP_JOB - elif job_input_format.lower() == "microsoft.qio.v2": - job_type = QIO_JOB - elif job_input_format.lower() == "qir.v1": - job_type = QIR_JOB + return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, + project, job_name, shots, storage, no_build, job_params, target_capability) else: - raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) - - if job_type == QIO_JOB: - return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, entry_point) - - if job_type == QIR_JOB: - return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, + return _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point) - if job_type == QSHARP_JOB: - return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, - project, job_name, shots, storage, no_build, job_params, target_capability) - -def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, +# def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, +# job_name, shots, storage, job_params, target_capability, +# job_input_file, job_input_format, job_output_format, entry_point): +def _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): """ - Submit QIO problem JSON or QIR bitcode to run on Azure Quantum. + Submit QIR bitcode, QIO problem JSON, or a pass-through job to run on Azure Quantum. """ + # Identify the type of job being submitted + lc_job_input_format = job_input_format.lower() + if lc_job_input_format == "qir.v1": + job_type = QIR_JOB + elif lc_job_input_format == "microsoft.qio.v2": + job_type = QIO_JOB + else: + # raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) + job_type = PASS_THROUGH_JOB + if job_output_format is None: - if job_type == QIO_JOB: - job_output_format = "microsoft.qio-results.v2" - elif job_type == QIR_JOB: + if job_type == QIR_JOB: job_output_format = "microsoft.quantum-results.v1" + elif job_type == QIO_JOB: + job_output_format = "microsoft.qio-results.v2" else: - raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + # raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) + # Look for an input file based on job_input_format if job_input_file is None: - if job_type == QIO_JOB: - input_file_extension = ".json" - elif job_type == QIR_JOB: + if job_type == QIR_JOB: input_file_extension = ".bc" + elif job_type == QIO_JOB: + input_file_extension = ".json" else: - raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) path = os.path.abspath(os.curdir) for file_name in os.listdir(path): @@ -247,7 +280,7 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name break if job_input_file is None: - raise RequiredArgumentMissingError("Failed to submit job: No --job-input-source path was specified.", JOB_SUBMIT_DOC_LINK_MSG) + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) # Prepare for input file upload according to job type if job_type == QIO_JOB: @@ -257,7 +290,11 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name return_sas_token = True with open(job_input_file, encoding="utf-8") as qio_file: uncompressed_blob_data = qio_file.read() - # Compress the input data (based on to_blob in qdk-python\azure-quantum\azure\quantum\optimization\problem.py) + + if "content_type" in uncompressed_blob_data and "application/x-protobuf" in uncompressed_blob_data: + raise InvalidArgumentValueError('Content type "application/x-protobuf" is not supported.') + + # Compress the input data (This code is based on to_blob in qdk-python\azure-quantum\azure\quantum\optimization\problem.py) data = io.BytesIO() with gzip.GzipFile(fileobj=data, mode="w") as fo: fo.write(uncompressed_blob_data.encode()) @@ -270,9 +307,14 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name return_sas_token = False with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() - + else: - raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + container_name_prefix = "cli-pass-through-job-" + content_type = None # <<<<< Should we get this from job_parameters? <<<<< + content_encoding = None + return_sas_token = False + with open(job_input_file, "rb") as qir_file: + blob_data = qir_file.read() # Upload the input file to the workspace's storage account if storage is None: @@ -302,8 +344,13 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name end_of_blob_name = blob_uri.find("?") container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] - # >>>>> TODO: Get more parameters from the command line <<<<< - input_params = {"params": {"timeout": 100}} + input_params = dict() + if job_params is None: + input_params = {"params": {"timeout": QIO_DEFAULT_TIMEOUT}} + else: + if "timeout" not in job_params: + job_params["timeout"] = QIO_DEFAULT_TIMEOUT + input_params["params"] = job_params elif job_type == QIR_JOB: container_uri = blob_uri[0:start_of_blob_name - 1] @@ -322,11 +369,12 @@ def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name if target_capability is None: target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? - # >>>>> TODO: Get more parameters from the command line <<<<< + # >>>>> TODO: Get parameters from the command line <<<<< input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} else: - raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) + input_params = job_params + # >>>>> Is this all we do for pass-through jobs? <<<<< client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 From e131d287eac1dbb48dd1ebec4f73a2e4c209ffa8 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 28 Nov 2022 11:50:54 -0800 Subject: [PATCH 31/65] Delete whitespace in blank lines to pass Static Analysis --- src/quantum/azext_quantum/operations/job.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 83e0e8d8470..14708f9f5d0 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -290,7 +290,7 @@ def _submit_directly_to_service(cmd, program_args, resource_group_name, workspac return_sas_token = True with open(job_input_file, encoding="utf-8") as qio_file: uncompressed_blob_data = qio_file.read() - + if "content_type" in uncompressed_blob_data and "application/x-protobuf" in uncompressed_blob_data: raise InvalidArgumentValueError('Content type "application/x-protobuf" is not supported.') @@ -307,7 +307,7 @@ def _submit_directly_to_service(cmd, program_args, resource_group_name, workspac return_sas_token = False with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() - + else: container_name_prefix = "cli-pass-through-job-" content_type = None # <<<<< Should we get this from job_parameters? <<<<< From 7d37cc4ef63f94f88047d72e4aaedc42cf5d0e99 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 13 Dec 2022 17:07:10 -0800 Subject: [PATCH 32/65] Enable pass-through jobs --- src/quantum/azext_quantum/_params.py | 2 +- src/quantum/azext_quantum/operations/job.py | 129 ++++++++++++++++---- 2 files changed, 108 insertions(+), 23 deletions(-) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index a48e02f065b..c74378aa53c 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -6,7 +6,7 @@ # pylint: disable=line-too-long,protected-access,no-self-use,too-many-statements import argparse -import json +# import json from knack.arguments import CLIArgumentType from azure.cli.core.azclierror import InvalidArgumentValueError, CLIError from azure.cli.core.util import shell_safe_json_parse diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 14708f9f5d0..b3ef5e805d3 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -17,9 +17,12 @@ from azure.cli.core.azclierror import (FileOperationError, AzureInternalError, InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) + +# from azure.quantum.optimization.problem import Problem from azure.quantum.storage import create_container, upload_blob -# from azure.quantum.optimization.problem import compress_protobuf -from azure.quantum.optimization.problem import Problem +from azure.quantum.target import Quantinuum, IonQ +from azure.quantum.target.rigetti.target import Rigetti + from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo @@ -230,21 +233,103 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar if job_input_format is None: return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability) - else: - return _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, - job_name, shots, storage, job_params, target_capability, - job_input_file, job_input_format, job_output_format, entry_point) + # else: + # return _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, + # job_name, shots, storage, job_params, target_capability, + # job_input_file, job_input_format, job_output_format, entry_point) + return _submit_directly_to_service(cmd, resource_group_name, workspace_name, location, target_id, + job_name, shots, storage, job_params, target_capability, + job_input_file, job_input_format, job_output_format, entry_point) + + +# def _get_default_job_parameters(provider, workspace): +# if provider == "quantinuum": +# target_parameters = Quantinuum(workspace) +# elif provider == "ionq": +# target_parameters = IonQ(workspace) +# elif provider == "rigetti": +# target_parameters = Rigetti(workspace) +# else: +# print("Provider not recognized") +# return +# +# if target_parameters is not None: +# default_input_format = target_parameters.input_data_format +# default_output_format = target_parameters.output_data_format +# default_content_type = target_parameters.content_type +# default_encoding = target_parameters.encoding + +# # >>>>>>>>>> +# print(f"provider = {provider}") +# print(f"input_format = {default_input_format}") +# print(f"output_format = {default_output_format}") +# print(f"content_type = {default_content_type}") +# print(f"encoding = {default_encoding}") +# else: +# print("Provider not recognized") +# +# return +# # <<<<<<<<<< # def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, # job_name, shots, storage, job_params, target_capability, # job_input_file, job_input_format, job_output_format, entry_point): -def _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, +def _submit_directly_to_service(cmd, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): """ Submit QIR bitcode, QIO problem JSON, or a pass-through job to run on Azure Quantum. """ + # Get workspace and target information + ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) + if ws_info is None: + raise AzureInternalError("Failed to get workspace information.") + target_info = TargetInfo(cmd, target_id) + if target_info is None: + raise AzureInternalError("Failed to get target information.") + provider = target_info.target_id.split('.')[0] + + # >>>>>>>>>> Is this useful??? >>>>>>>>>> + # Get default job parameters for this provider + if provider == "quantinuum": + target_parameters = Quantinuum(workspace_name) + elif provider == "ionq": + target_parameters = IonQ(workspace_name) + elif provider == "rigetti": + target_parameters = Rigetti(workspace_name) + else: + target_parameters = None + # print("Provider defaults not defined in qdk-python") + # return + + if target_parameters is None: + # default_input_format = None + default_output_format = None + default_content_type = None + default_encoding = None + else: + # default_input_format = target_parameters.input_data_format + default_output_format = target_parameters.output_data_format + default_content_type = target_parameters.content_type + default_encoding = target_parameters.encoding + + # >>>>>>>>>> + if job_output_format is None and default_output_format is not None: + job_output_format = default_output_format + # <<<<<<<<<< + + # >>>>>>>>>> + # print(f"provider = {provider}") + # print(f"input_format = {default_input_format}") + # print(f"output_format = {default_output_format}") + # print(f"content_type = {default_content_type}") + # print(f"encoding = {default_encoding}") + # else: + # print("Provider not recognized") + # return + # <<<<<<<<<< + # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() if lc_job_input_format == "qir.v1": @@ -310,8 +395,10 @@ def _submit_directly_to_service(cmd, program_args, resource_group_name, workspac else: container_name_prefix = "cli-pass-through-job-" - content_type = None # <<<<< Should we get this from job_parameters? <<<<< - content_encoding = None + # content_type = None # <<<<< Should we get this from job_params? <<<<< + # content_encoding = None + content_type = default_content_type + content_encoding = default_encoding return_sas_token = False with open(job_input_file, "rb") as qir_file: blob_data = qir_file.read() @@ -330,21 +417,14 @@ def _submit_directly_to_service(cmd, program_args, resource_group_name, workspac blob_name = "inputData" blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) - # Retrieve workspace and target information - ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) - if ws_info is None: - raise AzureInternalError("Failed to get workspace information.") - target_info = TargetInfo(cmd, target_id) - if target_info is None: - raise AzureInternalError("Failed to get target information.") - # Set the job parameters start_of_blob_name = blob_uri.find(blob_name) if job_type == QIO_JOB: end_of_blob_name = blob_uri.find("?") container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] - input_params = dict() + # input_params = dict() + input_params = {} if job_params is None: input_params = {"params": {"timeout": QIO_DEFAULT_TIMEOUT}} else: @@ -369,12 +449,17 @@ def _submit_directly_to_service(cmd, program_args, resource_group_name, workspac if target_capability is None: target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? - # >>>>> TODO: Get parameters from the command line <<<<< + # >>>>> TODO: Get additional parameters from the command line <<<<< input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} - + # if job_params is not None: + # input_params.extend(job_params) else: - input_params = job_params - # >>>>> Is this all we do for pass-through jobs? <<<<< + # input_params = job_params + # >>>>>>>>>> + container_uri = blob_uri[0:start_of_blob_name - 1] + input_params = {"count": 2} + # <<<<<<<<<< + # >>>>> TODO: Get additional parameters from the command line <<<<< client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 From df6f9d1349ce120e6cd8e598b7b72fcead3e8f54 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 14 Dec 2022 17:52:45 -0800 Subject: [PATCH 33/65] Handle provider names containing dots --- src/quantum/azext_quantum/operations/job.py | 28 ++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index b3ef5e805d3..748ab56d868 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -288,15 +288,26 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati target_info = TargetInfo(cmd, target_id) if target_info is None: raise AzureInternalError("Failed to get target information.") - provider = target_info.target_id.split('.')[0] + provider_id = target_info.target_id.split('.')[0] # <<<<< Is provider_id case sensitive? <<<<< + + # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id + if provider_id.lower() == "microsoft": + after_the_dot = target_info.target_id.split('.')[1] + if after_the_dot.lower() == "simulator" or after_the_dot.lower() == "fleetmanagement": # <<<<< Are there more like these? + provider_id = f"{provider_id}.{after_the_dot}" + + # >>>>>>>>>> + # print(f"provider_id = {provider_id}") + # return + # <<<<<<<<<< # >>>>>>>>>> Is this useful??? >>>>>>>>>> # Get default job parameters for this provider - if provider == "quantinuum": + if provider_id == "quantinuum": target_parameters = Quantinuum(workspace_name) - elif provider == "ionq": + elif provider_id == "ionq": target_parameters = IonQ(workspace_name) - elif provider == "rigetti": + elif provider_id == "rigetti": target_parameters = Rigetti(workspace_name) else: target_parameters = None @@ -314,13 +325,12 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati default_content_type = target_parameters.content_type default_encoding = target_parameters.encoding - # >>>>>>>>>> if job_output_format is None and default_output_format is not None: job_output_format = default_output_format # <<<<<<<<<< # >>>>>>>>>> - # print(f"provider = {provider}") + # print(f"provider_id = {provider_id}") # print(f"input_format = {default_input_format}") # print(f"output_format = {default_output_format}") # print(f"content_type = {default_content_type}") @@ -332,7 +342,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() - if lc_job_input_format == "qir.v1": + if lc_job_input_format == "qir.v1": # <<<<< <<<<<< What about Rigetti and Quantimuum QIR? job_type = QIR_JOB elif lc_job_input_format == "microsoft.qio.v2": job_type = QIO_JOB @@ -457,7 +467,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # input_params = job_params # >>>>>>>>>> container_uri = blob_uri[0:start_of_blob_name - 1] - input_params = {"count": 2} + input_params = {"count": 2} # <<<<< Is there a default for "count", like for "shots"? # <<<<<<<<<< # >>>>> TODO: Get additional parameters from the command line <<<<< @@ -467,7 +477,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati 'input_data_format': job_input_format, 'output_data_format': job_output_format, 'inputParams': input_params, - 'provider_id': target_info.target_id.split('.')[0], + 'provider_id': provider_id, 'target': target_info.target_id} # Submit the job From 1a6c6cbf04ddcaa8a2c3e97ec9c8a7a4d0ef2ed0 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 19 Dec 2022 12:50:23 -0800 Subject: [PATCH 34/65] Format inputParams correctly for QIR, QIO, and pass-through jobs --- src/quantum/azext_quantum/operations/job.py | 250 ++++++-------------- 1 file changed, 74 insertions(+), 176 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 748ab56d868..1c5062ae3c9 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -# pylint: disable=line-too-long,redefined-builtin,bare-except,inconsistent-return-statements +# pylint: disable=line-too-long,redefined-builtin,bare-except,inconsistent-return-statements,too-many-locals,too-many-branches,too-many-statements import gzip import io @@ -18,10 +18,7 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -# from azure.quantum.optimization.problem import Problem from azure.quantum.storage import create_container, upload_blob -from azure.quantum.target import Quantinuum, IonQ -from azure.quantum.target.rigetti.target import Rigetti from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo @@ -202,85 +199,22 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ - # # Identify the type of job being submitted - # if job_input_format is None: - # job_type = QSHARP_JOB - # elif job_input_format.lower() == "microsoft.qio.v2": - # job_type = QIO_JOB - # if job_input_file is not None and job_input_file.split(".")[-1].lower() == "pb": - # job_type = QIO_PB_JOB - # elif job_input_format.lower() == "qir.v1": - # job_type = QIR_JOB - # else: - # raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) - # - # if job_type == QIO_JOB: - # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format, entry_point) - # if job_type == QIO_PB_JOB: - # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format, entry_point) - # if job_type == QIR_JOB: - # return _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format, entry_point) - # if job_type == QSHARP_JOB: - # return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, - # project, job_name, shots, storage, no_build, job_params, target_capability) - if job_input_format is None: return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability) - # else: - # return _submit_directly_to_service(cmd, program_args, resource_group_name, workspace_name, location, target_id, - # job_name, shots, storage, job_params, target_capability, - # job_input_file, job_input_format, job_output_format, entry_point) + return _submit_directly_to_service(cmd, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point) -# def _get_default_job_parameters(provider, workspace): -# if provider == "quantinuum": -# target_parameters = Quantinuum(workspace) -# elif provider == "ionq": -# target_parameters = IonQ(workspace) -# elif provider == "rigetti": -# target_parameters = Rigetti(workspace) -# else: -# print("Provider not recognized") -# return -# -# if target_parameters is not None: -# default_input_format = target_parameters.input_data_format -# default_output_format = target_parameters.output_data_format -# default_content_type = target_parameters.content_type -# default_encoding = target_parameters.encoding - -# # >>>>>>>>>> -# print(f"provider = {provider}") -# print(f"input_format = {default_input_format}") -# print(f"output_format = {default_output_format}") -# print(f"content_type = {default_content_type}") -# print(f"encoding = {default_encoding}") -# else: -# print("Provider not recognized") -# -# return -# # <<<<<<<<<< - - -# def _submit_directly_to_service(cmd, job_type, program_args, resource_group_name, workspace_name, location, target_id, -# job_name, shots, storage, job_params, target_capability, -# job_input_file, job_input_format, job_output_format, entry_point): def _submit_directly_to_service(cmd, resource_group_name, workspace_name, location, target_id, job_name, shots, storage, job_params, target_capability, job_input_file, job_input_format, job_output_format, entry_point): """ Submit QIR bitcode, QIO problem JSON, or a pass-through job to run on Azure Quantum. """ + # Get workspace and target information ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) if ws_info is None: @@ -290,73 +224,28 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati raise AzureInternalError("Failed to get target information.") provider_id = target_info.target_id.split('.')[0] # <<<<< Is provider_id case sensitive? <<<<< - # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id + # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id: There might be a dot included if provider_id.lower() == "microsoft": after_the_dot = target_info.target_id.split('.')[1] - if after_the_dot.lower() == "simulator" or after_the_dot.lower() == "fleetmanagement": # <<<<< Are there more like these? + if after_the_dot.lower() == "simulator" or after_the_dot.lower() == "fleetmanagement": # <<<<< Are there more names like these? provider_id = f"{provider_id}.{after_the_dot}" - # >>>>>>>>>> - # print(f"provider_id = {provider_id}") - # return - # <<<<<<<<<< - - # >>>>>>>>>> Is this useful??? >>>>>>>>>> - # Get default job parameters for this provider - if provider_id == "quantinuum": - target_parameters = Quantinuum(workspace_name) - elif provider_id == "ionq": - target_parameters = IonQ(workspace_name) - elif provider_id == "rigetti": - target_parameters = Rigetti(workspace_name) - else: - target_parameters = None - # print("Provider defaults not defined in qdk-python") - # return - - if target_parameters is None: - # default_input_format = None - default_output_format = None - default_content_type = None - default_encoding = None - else: - # default_input_format = target_parameters.input_data_format - default_output_format = target_parameters.output_data_format - default_content_type = target_parameters.content_type - default_encoding = target_parameters.encoding - - if job_output_format is None and default_output_format is not None: - job_output_format = default_output_format - # <<<<<<<<<< - - # >>>>>>>>>> - # print(f"provider_id = {provider_id}") - # print(f"input_format = {default_input_format}") - # print(f"output_format = {default_output_format}") - # print(f"content_type = {default_content_type}") - # print(f"encoding = {default_encoding}") - # else: - # print("Provider not recognized") - # return - # <<<<<<<<<< - # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() - if lc_job_input_format == "qir.v1": # <<<<< <<<<<< What about Rigetti and Quantimuum QIR? + if "qir.v" in lc_job_input_format: # QCI uses "qir.v1", but Rigetti uses rigetti.qir.v1 <<<<< What about Quantinuum? job_type = QIR_JOB elif lc_job_input_format == "microsoft.qio.v2": job_type = QIO_JOB else: - # raise InvalidArgumentValueError(f"Job input format {job_input_format} is not supported.", JOB_SUBMIT_DOC_LINK_MSG) job_type = PASS_THROUGH_JOB + # If output format is not specified, attempt to supply default <<<<<<<<<< This section needs validation. Is this out-of-scope? if job_output_format is None: if job_type == QIR_JOB: - job_output_format = "microsoft.quantum-results.v1" + job_output_format = "microsoft.quantum-results.v1" # <<<<< This works for QCI, but is it OK for Rigetti and Quantinuum QIR? <<<<< elif job_type == QIO_JOB: job_output_format = "microsoft.qio-results.v2" else: - # raise InvalidArgumentValueError(JOB_TYPE_NOT_VALID_MSG) raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) # Look for an input file based on job_input_format @@ -377,16 +266,36 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if job_input_file is None: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) + # Extract the input-file-upload parameters from --job-parameters, then remove those parameters + # from job_params, since they should not be included in the inputParams property of job_details + content_type = None + content_encoding = None + return_sas_token = None + if job_params is not None: + if "content_type" in job_params.keys(): + content_type = job_params["content_type"] + del job_params["content_type"] + if "content_encoding" in job_params.keys(): + content_encoding = job_params["content_encoding"] + del job_params["content_encoding"] + if "return_sas_token" in job_params.keys(): + return_sas_token_str = job_params["return_sas_token"] + return_sas_token = return_sas_token_str.lower() == "true" + del job_params["return_sas_token"] + # Prepare for input file upload according to job type if job_type == QIO_JOB: container_name_prefix = "cli-qio-job-" - content_type = "application/json" - content_encoding = "gzip" - return_sas_token = True + if content_type is None: + content_type = "application/json" + if content_encoding is None: + content_encoding = "gzip" + if return_sas_token is None: + return_sas_token = True with open(job_input_file, encoding="utf-8") as qio_file: uncompressed_blob_data = qio_file.read() - if "content_type" in uncompressed_blob_data and "application/x-protobuf" in uncompressed_blob_data: + if ("content_type" in uncompressed_blob_data and "application/x-protobuf" in uncompressed_blob_data) or (content_type.lower() == "application/x-protobuf"): raise InvalidArgumentValueError('Content type "application/x-protobuf" is not supported.') # Compress the input data (This code is based on to_blob in qdk-python\azure-quantum\azure\quantum\optimization\problem.py) @@ -395,23 +304,20 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati fo.write(uncompressed_blob_data.encode()) blob_data = data.getvalue() - elif job_type == QIR_JOB: - container_name_prefix = "cli-qir-job-" - content_type = "application/x-qir.v1" - content_encoding = None - return_sas_token = False - with open(job_input_file, "rb") as qir_file: - blob_data = qir_file.read() - else: - container_name_prefix = "cli-pass-through-job-" - # content_type = None # <<<<< Should we get this from job_params? <<<<< - # content_encoding = None - content_type = default_content_type - content_encoding = default_encoding - return_sas_token = False - with open(job_input_file, "rb") as qir_file: - blob_data = qir_file.read() + if job_type == QIR_JOB: + container_name_prefix = "cli-qir-job-" + if content_type is None: + content_type = "application/x-qir.v1" # <<<<< Is this a valid default for all QIR jobs? + content_encoding = None + else: + container_name_prefix = "cli-pass-through-job-" + + if return_sas_token is None: + return_sas_token = False + + with open(job_input_file, "rb") as input_file: + blob_data = input_file.read() # Upload the input file to the workspace's storage account if storage is None: @@ -427,56 +333,48 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati blob_name = "inputData" blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) - # Set the job parameters + # Remove blob name from container URI start_of_blob_name = blob_uri.find(blob_name) - if job_type == QIO_JOB: + if return_sas_token: end_of_blob_name = blob_uri.find("?") container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] + else: + container_uri = blob_uri[0:start_of_blob_name - 1] + + # Combine separate command-line parameters (like shots, target_capability, and entry_point) with job_params + if job_params is None: + job_params = {} + if shots is not None: + job_params["shots"] = int(shots) + if target_capability is not None: + job_params["targetCapability"] = target_capability + if entry_point is not None: + job_params["entryPoint"] = entry_point + + # Make sure QIR jobs have an "arguments" parameter, even if it's empty + if job_type == QIR_JOB: + if "arguments" not in job_params: + job_params["arguments"] = [] + + # ...and supply a default "shots" if it's not specified (like Q# does) + if "shots" not in job_params: + job_params["shots"] = DEFAULT_SHOTS - # input_params = dict() - input_params = {} + if job_type == QIO_JOB: + # Convert to the QIO inputParams structure if job_params is None: - input_params = {"params": {"timeout": QIO_DEFAULT_TIMEOUT}} + job_params = {"params": {"timeout": QIO_DEFAULT_TIMEOUT}} else: if "timeout" not in job_params: job_params["timeout"] = QIO_DEFAULT_TIMEOUT - input_params["params"] = job_params - - elif job_type == QIR_JOB: - container_uri = blob_uri[0:start_of_blob_name - 1] - if shots is None: - shots = DEFAULT_SHOTS - else: - error_msg = "--shots value is not valid." - recommendation = "Enter a positive integer." - try: - shots = int(shots) - if shots < 1: - raise InvalidArgumentValueError(error_msg, recommendation) - except: - raise InvalidArgumentValueError(error_msg, recommendation) - - if target_capability is None: - target_capability = "AdaptiveExecution" # <<<<< Cesar said to use this for QCI. Does it apply to other providers? - - # >>>>> TODO: Get additional parameters from the command line <<<<< - input_params = {'arguments': [], 'name': job_name, 'targetCapability': target_capability, 'shots': shots, 'entryPoint': entry_point} - # if job_params is not None: - # input_params.extend(job_params) - else: - # input_params = job_params - # >>>>>>>>>> - container_uri = blob_uri[0:start_of_blob_name - 1] - input_params = {"count": 2} # <<<<< Is there a default for "count", like for "shots"? - # <<<<<<<<<< - # >>>>> TODO: Get additional parameters from the command line <<<<< + job_params = {"params": job_params} client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) - job_details = {'name': job_name, # job_details is defined in vendored_sdks\azure_quantum\models\_models_py3.py, starting at line 132 + job_details = {'name': job_name, 'container_uri': container_uri, 'input_data_format': job_input_format, 'output_data_format': job_output_format, - 'inputParams': input_params, + 'inputParams': job_params, 'provider_id': provider_id, 'target': target_info.target_id} From beff23e0a5f8a17e31f385c8e6bb8171f2eb2d2f Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 19 Dec 2022 15:34:14 -0800 Subject: [PATCH 35/65] Remove qdk-python dependencies --- src/quantum/azext_quantum/operations/job.py | 4 +- src/quantum/azext_quantum/storage.py | 383 ++++++++++++++++++++ src/quantum/setup.py | 1 - 3 files changed, 385 insertions(+), 3 deletions(-) create mode 100644 src/quantum/azext_quantum/storage.py diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 1c5062ae3c9..51ea408981b 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,8 +18,8 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -from azure.quantum.storage import create_container, upload_blob - +# from azure.quantum.storage import create_container, upload_blob +from ..storage import create_container, upload_blob from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo diff --git a/src/quantum/azext_quantum/storage.py b/src/quantum/azext_quantum/storage.py new file mode 100644 index 00000000000..23eda0a0673 --- /dev/null +++ b/src/quantum/azext_quantum/storage.py @@ -0,0 +1,383 @@ +## +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +## +import logging +from typing import Any, Dict +from azure.core import exceptions +from azure.storage.blob import ( + BlobServiceClient, + ContainerClient, + BlobClient, + BlobSasPermissions, + ContentSettings, + generate_blob_sas, + generate_container_sas, + BlobType, +) +from datetime import datetime, timedelta +from enum import Enum + +logger = logging.getLogger(__name__) + + +def create_container( + connection_string: str, container_name: str +) -> ContainerClient: + """ + Creates and initialize a container; returns the client needed to access it. + """ + blob_service_client = BlobServiceClient.from_connection_string( + connection_string + ) + logger.info( + f'{"Initializing storage client for account:"}' + + f"{blob_service_client.account_name}" + ) + + container_client = blob_service_client.get_container_client(container_name) + create_container_using_client(container_client) + return container_client + + +def create_container_using_client(container_client: ContainerClient): + """ + Creates the container if it doesn't already exist. + """ + if not container_client.exists(): + logger.debug( + f'{" - uploading to **new** container:"}' + f"{container_client.container_name}" + ) + container_client.create_container() + + +def get_container_uri(connection_string: str, container_name: str) -> str: + """ + Creates and initialize a container; + returns a URI with a SAS read/write token to access it. + """ + container = create_container(connection_string, container_name) + logger.info( + f'{"Creating SAS token for container"}' + + f"'{container_name}' on account: '{container.account_name}'" + ) + + sas_token = generate_container_sas( + container.account_name, + container.container_name, + account_key=container.credential.account_key, + permission=BlobSasPermissions( + read=True, add=True, write=True, create=True + ), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + uri = container.url + "?" + sas_token + logger.debug(f" - container url: '{uri}'.") + return uri + + +def upload_blob( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Uploading blob '{blob_name}'" + + f"to container '{container.container_name}'" + + f"on account: '{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + + blob = container.get_blob_client(blob_name) + + blob.upload_blob(data, content_settings=content_settings) + logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") + + if return_sas_token: + uri = get_blob_uri_with_sas_token(blob) + else: + uri = remove_sas_token(blob.url) + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +def append_blob( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, + metadata: Dict[str, str] = None, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Appending data to blob '{blob_name}'" + + f"in container '{container.container_name}'" + + f"on account: '{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + blob = container.get_blob_client(blob_name) + try: + props = blob.get_blob_properties() + if props.blob_type != BlobType.AppendBlob: + raise Exception("blob must be an append blob") + except exceptions.ResourceNotFoundError: + props = blob.create_append_blob( + content_settings=content_settings, metadata=metadata + ) + + blob.append_block(data, len(data)) + logger.debug(f" - blob '{blob_name}' appended. generating sas token.") + + if return_sas_token: + uri = get_blob_uri_with_sas_token(blob) + else: + uri = remove_sas_token(blob.url) + + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +def get_blob_uri_with_sas_token(blob: BlobClient): + """Returns a URI for the given blob that contains a SAS Token""" + sas_token = generate_blob_sas( + blob.account_name, + blob.container_name, + blob.blob_name, + account_key=blob.credential.account_key, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + return blob.url + "?" + sas_token + + +def download_blob(blob_url: str) -> Any: + """ + Downloads the given blob from the container. + """ + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Downloading blob '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}'" + + f"on account: '{blob_client.account_name}'" + ) + + response = blob_client.download_blob().readall() + logger.debug(response) + + return response + + +def download_blob_properties(blob_url: str) -> Dict[str, str]: + """Downloads the blob properties from Azure for the given blob URI""" + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Downloading blob properties '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}'" + + f"on account: '{blob_client.account_name}'" + ) + + response = blob_client.get_blob_properties() + logger.debug(response) + + return response + + +def download_blob_metadata(blob_url: str) -> Dict[str, str]: + """Downloads the blob metadata from the + blob properties in Azure for the given blob URI""" + return download_blob_properties(blob_url).metadata + + +def set_blob_metadata(blob_url: str, metadata: Dict[str, str]): + """Sets the provided dictionary as the metadata on the Azure blob""" + blob_client = BlobClient.from_blob_url(blob_url) + logger.info( + f"Setting blob properties '{blob_client.blob_name}'" + + f"from container '{blob_client.container_name}' on account:" + + f"'{blob_client.account_name}'" + ) + return blob_client.set_blob_metadata(metadata=metadata) + + +def remove_sas_token(sas_uri: str) -> str: + """Removes the SAS Token from the given URI if it contains one""" + index = sas_uri.find("?") + if index != -1: + sas_uri = sas_uri[0:index] + + return sas_uri + + +def init_blob_for_streaming_upload( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Streaming blob '{blob_name}'" + + f"to container '{container.container_name}' on account:" + + f"'{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + blob = container.get_blob_client(blob_name) + blob.stage_block() + blob.commit_block_list() + blob.upload_blob(data, content_settings=content_settings) + logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") + + if return_sas_token: + sas_token = generate_blob_sas( + blob.account_name, + blob.container_name, + blob.blob_name, + account_key=blob.credential.account_key, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + uri = blob.url + "?" + sas_token + else: + uri = remove_sas_token(blob.url) + + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +class StreamedBlobState(str, Enum): + not_initialized = 0 + uploading = 1 + committed = 2 + + +class StreamedBlob: + """Class that provides a state machine for writing + blobs using the Azure Block Blob API + + Internally implements a state machine for uploading blob data. + To use, start calling `upload_data()` + to add data blocks. Each call to `upload_data()` + will synchronously upload an individual block to Azure. + Once all blocks have been added, call `commit()` + to commit the blocks and make the blob available/readable. + + :param container: The container client that the blob will be uploaded to + :param blob_name: The name of the blob + (including optional path) within the blob container + :param content_type: The HTTP content type to apply to the blob metadata + :param content_encoding: The HTTP + content encoding to apply to the blob metadata + """ + + def __init__( + self, + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + ): + self.container = container + self.blob_name = blob_name + self.content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + self.state = StreamedBlobState.not_initialized + self.blob = container.get_blob_client(blob_name) + self.blocks = [] + + def upload_data(self, data): + """Synchronously uploads a block to the given block blob in Azure + + :param data: The data to be uploaded as a block. + :type data: Union[Iterable[AnyStr], IO[AnyStr]] + """ + if self.state == StreamedBlobState.not_initialized: + create_container_using_client(self.container) + logger.info( + f"Streaming blob '{self.blob_name}' to container" + + f"'{self.container.container_name}'" + + f"on account: '{self.container.account_name}'" + ) + self.initialized = True + + self.state = StreamedBlobState.uploading + id = self._get_next_block_id() + logger.debug(f"Uploading block '{id}' to {self.blob_name}") + self.blob.stage_block(id, data, length=len(data)) + self.blocks.append(id) + + def commit(self, metadata: Dict[str, str] = None): + """Synchronously commits all previously + uploaded blobs to the block blob + + :param metadata: Optional dictionary of + metadata to be applied to the block blob + """ + if self.state == StreamedBlobState.not_initialized: + raise Exception("StreamedBlob cannot commit before uploading data") + elif self.state == StreamedBlobState.committed: + raise Exception("StreamedBlob is already committed") + + logger.debug(f"Committing {len(self.blocks)} blocks {self.blob_name}") + self.blob.commit_block_list( + self.blocks, + content_settings=self.content_settings, + metadata=metadata, + ) + self.state = StreamedBlobState.committed + logger.debug(f"Committed {self.blob_name}") + + def getUri(self, with_sas_token: bool = False): + """Gets the full Azure Storage URI for the + uploaded blob after it has been committed""" + if self.state != StreamedBlobState.committed: + raise Exception("Can only retrieve sas token for committed blob") + if with_sas_token: + return get_blob_uri_with_sas_token(self.blob) + + return remove_sas_token(self.blob.url) + + def _get_next_block_id(self): + return f"{len(self.blocks):10}" diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 068eb291999..6ec07847d77 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -34,7 +34,6 @@ ] DEPENDENCIES = [ - 'azure-quantum~=0.27.238334' ] with open('README.rst', 'r', encoding='utf-8') as f: From 10bd24796ae920aea2a9dd9027b67faaad420c30 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 19 Dec 2022 15:55:52 -0800 Subject: [PATCH 36/65] Replace license header in storage.py --- src/quantum/azext_quantum/storage.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/quantum/azext_quantum/storage.py b/src/quantum/azext_quantum/storage.py index 23eda0a0673..6a393815786 100644 --- a/src/quantum/azext_quantum/storage.py +++ b/src/quantum/azext_quantum/storage.py @@ -1,7 +1,8 @@ -## +# -------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. -## +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + import logging from typing import Any, Dict from azure.core import exceptions From f7e64fce39f5d4514a7ef460d5d38324510ce135 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 19 Dec 2022 16:19:32 -0800 Subject: [PATCH 37/65] Add dependency on azure-storage-blob package --- src/quantum/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 6ec07847d77..7136ee2d199 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -34,6 +34,7 @@ ] DEPENDENCIES = [ + 'azure-storage-blob~=12.14.1' ] with open('README.rst', 'r', encoding='utf-8') as f: From 5edae46721b782b2d50eecfabc01fd8c4aca9604 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 20 Dec 2022 17:19:12 -0800 Subject: [PATCH 38/65] Restore qdk-python (azure-quantum) storage dependency and remove explicit azure-storage-blob dependency --- src/quantum/azext_quantum/operations/job.py | 16 +- src/quantum/azext_quantum/storage.py | 384 -------------------- src/quantum/setup.py | 2 +- 3 files changed, 9 insertions(+), 393 deletions(-) delete mode 100644 src/quantum/azext_quantum/storage.py diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 51ea408981b..ecc4b395af2 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,8 +18,8 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -# from azure.quantum.storage import create_container, upload_blob -from ..storage import create_container, upload_blob +from azure.quantum.storage import create_container, upload_blob + from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo from .target import TargetInfo @@ -32,7 +32,6 @@ ERROR_MSG_MISSING_INPUT_FILE = "The following argument is required: --job-input-file" # NOTE: The Azure CLI core generates a similar error message, but "the" is lowercase and "arguments" is always plural. ERROR_MSG_MISSING_OUTPUT_FORMAT = "The following argument is required: --job-output-format" JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" -JOB_TYPE_NOT_VALID_MSG = "Job type not recognized. This is a bug!" # Job types QIO_JOB = 1 @@ -239,10 +238,10 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: job_type = PASS_THROUGH_JOB - # If output format is not specified, attempt to supply default <<<<<<<<<< This section needs validation. Is this out-of-scope? + # If output format is not specified, supply a default for QIR or QIO jobs if job_output_format is None: if job_type == QIR_JOB: - job_output_format = "microsoft.quantum-results.v1" # <<<<< This works for QCI, but is it OK for Rigetti and Quantinuum QIR? <<<<< + job_output_format = "microsoft.quantum-results.v1" # <<<<< This works for QCI, but is it OK for Rigetti and Quantinuum QIR? <<<<< elif job_type == QIO_JOB: job_output_format = "microsoft.qio-results.v2" else: @@ -324,13 +323,13 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati from .workspace import get as ws_get ws = ws_get(cmd) storage = ws.storage_account.split('/')[-1] - job_id = str(uuid.uuid4()) container_name = container_name_prefix + job_id connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] container_client = create_container(connection_string, container_name) blob_name = "inputData" + knack_logger.warning('Uploading input data...') blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) # Remove blob name from container URI @@ -360,8 +359,8 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if "shots" not in job_params: job_params["shots"] = DEFAULT_SHOTS + # For QIO jobs, start inputParams with a "params" key and supply a default timeout if job_type == QIO_JOB: - # Convert to the QIO inputParams structure if job_params is None: job_params = {"params": {"timeout": QIO_DEFAULT_TIMEOUT}} else: @@ -369,6 +368,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati job_params["timeout"] = QIO_DEFAULT_TIMEOUT job_params = {"params": job_params} + # Submit the job client = cf_jobs(cmd.cli_ctx, ws_info.subscription, ws_info.resource_group, ws_info.name, ws_info.location) job_details = {'name': job_name, 'container_uri': container_uri, @@ -378,7 +378,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati 'provider_id': provider_id, 'target': target_info.target_id} - # Submit the job + knack_logger.warning('Submitting job...') return client.create(job_id, job_details) diff --git a/src/quantum/azext_quantum/storage.py b/src/quantum/azext_quantum/storage.py deleted file mode 100644 index 6a393815786..00000000000 --- a/src/quantum/azext_quantum/storage.py +++ /dev/null @@ -1,384 +0,0 @@ -# -------------------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# -------------------------------------------------------------------------------------------- - -import logging -from typing import Any, Dict -from azure.core import exceptions -from azure.storage.blob import ( - BlobServiceClient, - ContainerClient, - BlobClient, - BlobSasPermissions, - ContentSettings, - generate_blob_sas, - generate_container_sas, - BlobType, -) -from datetime import datetime, timedelta -from enum import Enum - -logger = logging.getLogger(__name__) - - -def create_container( - connection_string: str, container_name: str -) -> ContainerClient: - """ - Creates and initialize a container; returns the client needed to access it. - """ - blob_service_client = BlobServiceClient.from_connection_string( - connection_string - ) - logger.info( - f'{"Initializing storage client for account:"}' - + f"{blob_service_client.account_name}" - ) - - container_client = blob_service_client.get_container_client(container_name) - create_container_using_client(container_client) - return container_client - - -def create_container_using_client(container_client: ContainerClient): - """ - Creates the container if it doesn't already exist. - """ - if not container_client.exists(): - logger.debug( - f'{" - uploading to **new** container:"}' - f"{container_client.container_name}" - ) - container_client.create_container() - - -def get_container_uri(connection_string: str, container_name: str) -> str: - """ - Creates and initialize a container; - returns a URI with a SAS read/write token to access it. - """ - container = create_container(connection_string, container_name) - logger.info( - f'{"Creating SAS token for container"}' - + f"'{container_name}' on account: '{container.account_name}'" - ) - - sas_token = generate_container_sas( - container.account_name, - container.container_name, - account_key=container.credential.account_key, - permission=BlobSasPermissions( - read=True, add=True, write=True, create=True - ), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - uri = container.url + "?" + sas_token - logger.debug(f" - container url: '{uri}'.") - return uri - - -def upload_blob( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Uploading blob '{blob_name}'" - + f"to container '{container.container_name}'" - + f"on account: '{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - - blob = container.get_blob_client(blob_name) - - blob.upload_blob(data, content_settings=content_settings) - logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") - - if return_sas_token: - uri = get_blob_uri_with_sas_token(blob) - else: - uri = remove_sas_token(blob.url) - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -def append_blob( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, - metadata: Dict[str, str] = None, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Appending data to blob '{blob_name}'" - + f"in container '{container.container_name}'" - + f"on account: '{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - blob = container.get_blob_client(blob_name) - try: - props = blob.get_blob_properties() - if props.blob_type != BlobType.AppendBlob: - raise Exception("blob must be an append blob") - except exceptions.ResourceNotFoundError: - props = blob.create_append_blob( - content_settings=content_settings, metadata=metadata - ) - - blob.append_block(data, len(data)) - logger.debug(f" - blob '{blob_name}' appended. generating sas token.") - - if return_sas_token: - uri = get_blob_uri_with_sas_token(blob) - else: - uri = remove_sas_token(blob.url) - - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -def get_blob_uri_with_sas_token(blob: BlobClient): - """Returns a URI for the given blob that contains a SAS Token""" - sas_token = generate_blob_sas( - blob.account_name, - blob.container_name, - blob.blob_name, - account_key=blob.credential.account_key, - permission=BlobSasPermissions(read=True), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - return blob.url + "?" + sas_token - - -def download_blob(blob_url: str) -> Any: - """ - Downloads the given blob from the container. - """ - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Downloading blob '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}'" - + f"on account: '{blob_client.account_name}'" - ) - - response = blob_client.download_blob().readall() - logger.debug(response) - - return response - - -def download_blob_properties(blob_url: str) -> Dict[str, str]: - """Downloads the blob properties from Azure for the given blob URI""" - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Downloading blob properties '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}'" - + f"on account: '{blob_client.account_name}'" - ) - - response = blob_client.get_blob_properties() - logger.debug(response) - - return response - - -def download_blob_metadata(blob_url: str) -> Dict[str, str]: - """Downloads the blob metadata from the - blob properties in Azure for the given blob URI""" - return download_blob_properties(blob_url).metadata - - -def set_blob_metadata(blob_url: str, metadata: Dict[str, str]): - """Sets the provided dictionary as the metadata on the Azure blob""" - blob_client = BlobClient.from_blob_url(blob_url) - logger.info( - f"Setting blob properties '{blob_client.blob_name}'" - + f"from container '{blob_client.container_name}' on account:" - + f"'{blob_client.account_name}'" - ) - return blob_client.set_blob_metadata(metadata=metadata) - - -def remove_sas_token(sas_uri: str) -> str: - """Removes the SAS Token from the given URI if it contains one""" - index = sas_uri.find("?") - if index != -1: - sas_uri = sas_uri[0:index] - - return sas_uri - - -def init_blob_for_streaming_upload( - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - data: Any, - return_sas_token: bool = True, -) -> str: - """ - Uploads the given data to a blob record. - If a blob with the given name already exist, it throws an error. - - Returns a uri with a SAS token to access the newly created blob. - """ - create_container_using_client(container) - logger.info( - f"Streaming blob '{blob_name}'" - + f"to container '{container.container_name}' on account:" - + f"'{container.account_name}'" - ) - - content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - blob = container.get_blob_client(blob_name) - blob.stage_block() - blob.commit_block_list() - blob.upload_blob(data, content_settings=content_settings) - logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") - - if return_sas_token: - sas_token = generate_blob_sas( - blob.account_name, - blob.container_name, - blob.blob_name, - account_key=blob.credential.account_key, - permission=BlobSasPermissions(read=True), - expiry=datetime.utcnow() + timedelta(days=14), - ) - - uri = blob.url + "?" + sas_token - else: - uri = remove_sas_token(blob.url) - - logger.debug(f" - blob access url: '{uri}'.") - - return uri - - -class StreamedBlobState(str, Enum): - not_initialized = 0 - uploading = 1 - committed = 2 - - -class StreamedBlob: - """Class that provides a state machine for writing - blobs using the Azure Block Blob API - - Internally implements a state machine for uploading blob data. - To use, start calling `upload_data()` - to add data blocks. Each call to `upload_data()` - will synchronously upload an individual block to Azure. - Once all blocks have been added, call `commit()` - to commit the blocks and make the blob available/readable. - - :param container: The container client that the blob will be uploaded to - :param blob_name: The name of the blob - (including optional path) within the blob container - :param content_type: The HTTP content type to apply to the blob metadata - :param content_encoding: The HTTP - content encoding to apply to the blob metadata - """ - - def __init__( - self, - container: ContainerClient, - blob_name: str, - content_type: str, - content_encoding: str, - ): - self.container = container - self.blob_name = blob_name - self.content_settings = ContentSettings( - content_type=content_type, content_encoding=content_encoding - ) - self.state = StreamedBlobState.not_initialized - self.blob = container.get_blob_client(blob_name) - self.blocks = [] - - def upload_data(self, data): - """Synchronously uploads a block to the given block blob in Azure - - :param data: The data to be uploaded as a block. - :type data: Union[Iterable[AnyStr], IO[AnyStr]] - """ - if self.state == StreamedBlobState.not_initialized: - create_container_using_client(self.container) - logger.info( - f"Streaming blob '{self.blob_name}' to container" - + f"'{self.container.container_name}'" - + f"on account: '{self.container.account_name}'" - ) - self.initialized = True - - self.state = StreamedBlobState.uploading - id = self._get_next_block_id() - logger.debug(f"Uploading block '{id}' to {self.blob_name}") - self.blob.stage_block(id, data, length=len(data)) - self.blocks.append(id) - - def commit(self, metadata: Dict[str, str] = None): - """Synchronously commits all previously - uploaded blobs to the block blob - - :param metadata: Optional dictionary of - metadata to be applied to the block blob - """ - if self.state == StreamedBlobState.not_initialized: - raise Exception("StreamedBlob cannot commit before uploading data") - elif self.state == StreamedBlobState.committed: - raise Exception("StreamedBlob is already committed") - - logger.debug(f"Committing {len(self.blocks)} blocks {self.blob_name}") - self.blob.commit_block_list( - self.blocks, - content_settings=self.content_settings, - metadata=metadata, - ) - self.state = StreamedBlobState.committed - logger.debug(f"Committed {self.blob_name}") - - def getUri(self, with_sas_token: bool = False): - """Gets the full Azure Storage URI for the - uploaded blob after it has been committed""" - if self.state != StreamedBlobState.committed: - raise Exception("Can only retrieve sas token for committed blob") - if with_sas_token: - return get_blob_uri_with_sas_token(self.blob) - - return remove_sas_token(self.blob.url) - - def _get_next_block_id(self): - return f"{len(self.blocks):10}" diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 7136ee2d199..5a53630a261 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -34,7 +34,7 @@ ] DEPENDENCIES = [ - 'azure-storage-blob~=12.14.1' + 'azure-quantum~=0.27.244707' ] with open('README.rst', 'r', encoding='utf-8') as f: From 69055f1cc29b4e9a4ef00ee43a942b7cf5ffe4f0 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 22 Dec 2022 11:38:52 -0800 Subject: [PATCH 39/65] Add a stripped-down storage.py to this repo --- src/quantum/azext_quantum/operations/job.py | 3 +- src/quantum/azext_quantum/storage.py | 115 ++++++++++++++++++++ src/quantum/setup.py | 2 +- 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/quantum/azext_quantum/storage.py diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index ecc4b395af2..e48f3cfd3f4 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,7 +18,8 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -from azure.quantum.storage import create_container, upload_blob +# from azure.quantum.storage import create_container, upload_blob +from ..storage import create_container, upload_blob from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo diff --git a/src/quantum/azext_quantum/storage.py b/src/quantum/azext_quantum/storage.py new file mode 100644 index 00000000000..d98a5464382 --- /dev/null +++ b/src/quantum/azext_quantum/storage.py @@ -0,0 +1,115 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# This file is a reduced version of qdk-python/azure-quantum/azure/quantum/target/target.py +# It only contains the functions required to do inputData blob upload for job submission. + +# Unused imports were removed to reduce Pylint style-rule violations. +import logging +from datetime import datetime, timedelta +from typing import Any +from azure.storage.blob import ( + BlobServiceClient, + ContainerClient, + BlobClient, + BlobSasPermissions, + ContentSettings, + generate_blob_sas, +) + +logger = logging.getLogger(__name__) + + +def create_container( + connection_string: str, container_name: str +) -> ContainerClient: + """ + Creates and initialize a container; returns the client needed to access it. + """ + blob_service_client = BlobServiceClient.from_connection_string( + connection_string + ) + logger.info( + f'{"Initializing storage client for account:"}' + + f"{blob_service_client.account_name}" + ) + + container_client = blob_service_client.get_container_client(container_name) + create_container_using_client(container_client) + return container_client + + +def create_container_using_client(container_client: ContainerClient): + """ + Creates the container if it doesn't already exist. + """ + if not container_client.exists(): + logger.debug( + f'{" - uploading to **new** container:"}' + f"{container_client.container_name}" + ) + container_client.create_container() + + +def upload_blob( + container: ContainerClient, + blob_name: str, + content_type: str, + content_encoding: str, + data: Any, + return_sas_token: bool = True, +) -> str: + """ + Uploads the given data to a blob record. + If a blob with the given name already exist, it throws an error. + + Returns a uri with a SAS token to access the newly created blob. + """ + create_container_using_client(container) + logger.info( + f"Uploading blob '{blob_name}'" + + f"to container '{container.container_name}'" + + f"on account: '{container.account_name}'" + ) + + content_settings = ContentSettings( + content_type=content_type, content_encoding=content_encoding + ) + + blob = container.get_blob_client(blob_name) + + blob.upload_blob(data, content_settings=content_settings) + logger.debug(f" - blob '{blob_name}' uploaded. generating sas token.") + + if return_sas_token: + uri = get_blob_uri_with_sas_token(blob) + else: + uri = remove_sas_token(blob.url) + logger.debug(f" - blob access url: '{uri}'.") + + return uri + + +def get_blob_uri_with_sas_token(blob: BlobClient): + """Returns a URI for the given blob that contains a SAS Token""" + sas_token = generate_blob_sas( + blob.account_name, + blob.container_name, + blob.blob_name, + account_key=blob.credential.account_key, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(days=14), + ) + + return blob.url + "?" + sas_token + + +def remove_sas_token(sas_uri: str) -> str: + """Removes the SAS Token from the given URI if it contains one""" + index = sas_uri.find("?") + if index != -1: + sas_uri = sas_uri[0:index] + + return sas_uri diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 5a53630a261..7136ee2d199 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -34,7 +34,7 @@ ] DEPENDENCIES = [ - 'azure-quantum~=0.27.244707' + 'azure-storage-blob~=12.14.1' ] with open('README.rst', 'r', encoding='utf-8') as f: From ccd5d97320eb1af0d1448a03a83ca9c70f8e7a68 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 22 Dec 2022 17:47:38 -0800 Subject: [PATCH 40/65] Convert count to an integer --- src/quantum/azext_quantum/operations/job.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index e48f3cfd3f4..80e50e02887 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -351,6 +351,10 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if entry_point is not None: job_params["entryPoint"] = entry_point + # Convert "count" to an integer + if "count" in job_params.keys(): + job_params["count"] = int(job_params["count"]) + # Make sure QIR jobs have an "arguments" parameter, even if it's empty if job_type == QIR_JOB: if "arguments" not in job_params: From d002f3b430c7264daf2f526c9053396ce8709d0d Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 3 Jan 2023 14:53:14 -0800 Subject: [PATCH 41/65] Revise and delete comments --- src/quantum/azext_quantum/_params.py | 4 ---- src/quantum/azext_quantum/operations/job.py | 7 ++++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index c74378aa53c..c49499e6eab 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -6,7 +6,6 @@ # pylint: disable=line-too-long,protected-access,no-self-use,too-many-statements import argparse -# import json from knack.arguments import CLIArgumentType from azure.cli.core.azclierror import InvalidArgumentValueError, CLIError from azure.cli.core.util import shell_safe_json_parse @@ -53,7 +52,6 @@ def load_arguments(self, _): provider_sku_list_type = CLIArgumentType(options_list=['--provider-sku-list', '-r'], help='Comma separated list of Provider/SKU pairs. Separate the Provider and SKU with a slash. Enclose the entire list in quotes. Values from `az quantum offerings list -l -o table`') auto_accept_type = CLIArgumentType(help='If specified, provider terms are accepted without an interactive Y/N prompt.') autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') - # job_input_source_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension is based on --job-input-type') job_input_file_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension is based on --job-input-type') job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') job_output_format_type = CLIArgumentType(help='The expected job output format.') @@ -89,7 +87,6 @@ def load_arguments(self, _): with self.argument_context('quantum job submit') as c: c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # c.argument('job_input_source', job_input_source_type) c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) @@ -106,7 +103,6 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # c.argument('job_input_source', job_input_source_type) c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 80e50e02887..59b1340df71 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -224,7 +224,8 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati raise AzureInternalError("Failed to get target information.") provider_id = target_info.target_id.split('.')[0] # <<<<< Is provider_id case sensitive? <<<<< - # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id: There might be a dot included + # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id values: + # A first-party provider ID might might have a dot in it. if provider_id.lower() == "microsoft": after_the_dot = target_info.target_id.split('.')[1] if after_the_dot.lower() == "simulator" or after_the_dot.lower() == "fleetmanagement": # <<<<< Are there more names like these? @@ -239,7 +240,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: job_type = PASS_THROUGH_JOB - # If output format is not specified, supply a default for QIR or QIO jobs + # If output format is not specified, supply a default for QIR or QIO jobs # <<<<< Is this out-of-scope? if job_output_format is None: if job_type == QIR_JOB: job_output_format = "microsoft.quantum-results.v1" # <<<<< This works for QCI, but is it OK for Rigetti and Quantinuum QIR? <<<<< @@ -351,7 +352,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if entry_point is not None: job_params["entryPoint"] = entry_point - # Convert "count" to an integer + # Convert "count" to an integer # <<<<< What about other numeric or Boolean values? Convert them too? if "count" in job_params.keys(): job_params["count"] = int(job_params["count"]) From 1a3c1d99224f92d5c47c834d2478aa3a81e743bb Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 3 Jan 2023 18:09:16 -0800 Subject: [PATCH 42/65] Never return a SAS token. Simplify container names. --- src/quantum/azext_quantum/operations/job.py | 47 ++++++++++----------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 59b1340df71..23ec979d6bb 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -233,7 +233,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() - if "qir.v" in lc_job_input_format: # QCI uses "qir.v1", but Rigetti uses rigetti.qir.v1 <<<<< What about Quantinuum? + if "qir.v" in lc_job_input_format: # QCI uses "qir.v1", but Rigetti uses "rigetti.qir.v1" and Quantinuum uses "honeywell.qir.v1" job_type = QIR_JOB elif lc_job_input_format == "microsoft.qio.v2": job_type = QIO_JOB @@ -271,7 +271,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # from job_params, since they should not be included in the inputParams property of job_details content_type = None content_encoding = None - return_sas_token = None + # return_sas_token = None if job_params is not None: if "content_type" in job_params.keys(): content_type = job_params["content_type"] @@ -279,20 +279,20 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if "content_encoding" in job_params.keys(): content_encoding = job_params["content_encoding"] del job_params["content_encoding"] - if "return_sas_token" in job_params.keys(): - return_sas_token_str = job_params["return_sas_token"] - return_sas_token = return_sas_token_str.lower() == "true" - del job_params["return_sas_token"] + # if "return_sas_token" in job_params.keys(): + # return_sas_token_str = job_params["return_sas_token"] + # return_sas_token = return_sas_token_str.lower() == "true" + # del job_params["return_sas_token"] # Prepare for input file upload according to job type if job_type == QIO_JOB: - container_name_prefix = "cli-qio-job-" + # container_name_prefix = "cli-qio-job-" if content_type is None: content_type = "application/json" if content_encoding is None: content_encoding = "gzip" - if return_sas_token is None: - return_sas_token = True + # if return_sas_token is None: + # return_sas_token = True with open(job_input_file, encoding="utf-8") as qio_file: uncompressed_blob_data = qio_file.read() @@ -307,15 +307,15 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: if job_type == QIR_JOB: - container_name_prefix = "cli-qir-job-" + # container_name_prefix = "cli-qir-job-" if content_type is None: content_type = "application/x-qir.v1" # <<<<< Is this a valid default for all QIR jobs? content_encoding = None - else: - container_name_prefix = "cli-pass-through-job-" + # else: + # container_name_prefix = "cli-pass-through-job-" - if return_sas_token is None: - return_sas_token = False + # if return_sas_token is None: + # return_sas_token = False with open(job_input_file, "rb") as input_file: blob_data = input_file.read() @@ -326,21 +326,20 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati ws = ws_get(cmd) storage = ws.storage_account.split('/')[-1] job_id = str(uuid.uuid4()) - container_name = container_name_prefix + job_id + container_name = "quantum-job-" + job_id connection_string_dict = show_storage_account_connection_string(cmd, resource_group_name, storage) connection_string = connection_string_dict["connectionString"] container_client = create_container(connection_string, container_name) blob_name = "inputData" - knack_logger.warning('Uploading input data...') - blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, return_sas_token) - # Remove blob name from container URI + knack_logger.warning("Uploading input data...") + try: + blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, False) + except: + raise AzureResponseError("Upload failed. Please try submitting the job again.") + start_of_blob_name = blob_uri.find(blob_name) - if return_sas_token: - end_of_blob_name = blob_uri.find("?") - container_uri = blob_uri[0:start_of_blob_name - 1] + blob_uri[end_of_blob_name:] - else: - container_uri = blob_uri[0:start_of_blob_name - 1] + container_uri = blob_uri[0:start_of_blob_name - 1] # Combine separate command-line parameters (like shots, target_capability, and entry_point) with job_params if job_params is None: @@ -384,7 +383,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati 'provider_id': provider_id, 'target': target_info.target_id} - knack_logger.warning('Submitting job...') + knack_logger.warning("Submitting job...") return client.create(job_id, job_details) From a63179b3e3d2a8aee39afe7248b6927bdccc2c70 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 4 Jan 2023 09:21:49 -0800 Subject: [PATCH 43/65] Handle upload errors --- src/quantum/azext_quantum/_params.py | 1 - src/quantum/azext_quantum/operations/job.py | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index c49499e6eab..194494395a0 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -119,7 +119,6 @@ def load_arguments(self, _): c.argument('no_build', no_build_type) c.argument('job_params', job_params_type) c.argument('target_capability', target_capability_type) - # c.argument('job_input_source', job_input_source_type) c.argument('job_input_file', job_input_file_type) c.argument('job_input_format', job_input_format_type) c.argument('job_output_format', job_output_format_type) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 23ec979d6bb..c5ab01ba1f5 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -271,7 +271,6 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # from job_params, since they should not be included in the inputParams property of job_details content_type = None content_encoding = None - # return_sas_token = None if job_params is not None: if "content_type" in job_params.keys(): content_type = job_params["content_type"] @@ -279,20 +278,13 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if "content_encoding" in job_params.keys(): content_encoding = job_params["content_encoding"] del job_params["content_encoding"] - # if "return_sas_token" in job_params.keys(): - # return_sas_token_str = job_params["return_sas_token"] - # return_sas_token = return_sas_token_str.lower() == "true" - # del job_params["return_sas_token"] # Prepare for input file upload according to job type if job_type == QIO_JOB: - # container_name_prefix = "cli-qio-job-" if content_type is None: content_type = "application/json" if content_encoding is None: content_encoding = "gzip" - # if return_sas_token is None: - # return_sas_token = True with open(job_input_file, encoding="utf-8") as qio_file: uncompressed_blob_data = qio_file.read() @@ -307,15 +299,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: if job_type == QIR_JOB: - # container_name_prefix = "cli-qir-job-" if content_type is None: content_type = "application/x-qir.v1" # <<<<< Is this a valid default for all QIR jobs? content_encoding = None - # else: - # container_name_prefix = "cli-pass-through-job-" - - # if return_sas_token is None: - # return_sas_token = False with open(job_input_file, "rb") as input_file: blob_data = input_file.read() From 119f78f095bbbcb912bba96d2145b05a20cf93a1 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 5 Jan 2023 15:33:30 -0800 Subject: [PATCH 44/65] Add get_provider function --- src/quantum/azext_quantum/operations/job.py | 14 ++++---------- src/quantum/azext_quantum/operations/target.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index c5ab01ba1f5..cc824a73e91 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,12 +18,11 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -# from azure.quantum.storage import create_container, upload_blob from ..storage import create_container, upload_blob from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo -from .target import TargetInfo +from .target import TargetInfo, get_provider MINIMUM_MAX_POLL_WAIT_SECS = 1 @@ -222,14 +221,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati target_info = TargetInfo(cmd, target_id) if target_info is None: raise AzureInternalError("Failed to get target information.") - provider_id = target_info.target_id.split('.')[0] # <<<<< Is provider_id case sensitive? <<<<< - - # Microsoft provider_id values don't follow the same pattern as all the other companies' provider_id values: - # A first-party provider ID might might have a dot in it. - if provider_id.lower() == "microsoft": - after_the_dot = target_info.target_id.split('.')[1] - if after_the_dot.lower() == "simulator" or after_the_dot.lower() == "fleetmanagement": # <<<<< Are there more names like these? - provider_id = f"{provider_id}.{after_the_dot}" + provider_id = get_provider(cmd, target_info.target_id, resource_group_name, workspace_name, location) + if provider_id is None: + raise AzureInternalError(f"Failed to find a Provider ID for the specified Target ID, {target_info.target_id}") # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() diff --git a/src/quantum/azext_quantum/operations/target.py b/src/quantum/azext_quantum/operations/target.py index ce93669f7fe..0bbf0243eae 100644 --- a/src/quantum/azext_quantum/operations/target.py +++ b/src/quantum/azext_quantum/operations/target.py @@ -75,3 +75,20 @@ def target_show(cmd, target_id): info = TargetInfo(cmd, target_id) info.target_id += "" # Kludge excuse: Without this the only output we ever get is "targetId": {"isDefault": true} return info + + +def get_provider(cmd, target_id, resource_group_name, workspace_name, location): + """ + Get the the Provider ID for a specific target + """ + provider_id = None + provider_list = list(cmd, resource_group_name, workspace_name, location) + if provider_list is not None: + for item in provider_list: + for target_item in item.targets: + if target_item.id.lower() == target_id.lower(): + provider_id = item.id + break + if provider_id is not None: + break + return provider_id From 39a97e3672d82b923c2cf19da755157d5368a373 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 5 Jan 2023 18:16:39 -0800 Subject: [PATCH 45/65] Handle conversion errors from int(shots) and int(count) --- src/quantum/azext_quantum/operations/job.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index cc824a73e91..5a64fc9108f 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -325,7 +325,10 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if job_params is None: job_params = {} if shots is not None: - job_params["shots"] = int(shots) + try: + job_params["shots"] = int(shots) + except: + raise InvalidArgumentValueError("Invalid --shots value. Shots must be an integer.") if target_capability is not None: job_params["targetCapability"] = target_capability if entry_point is not None: @@ -333,7 +336,10 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # Convert "count" to an integer # <<<<< What about other numeric or Boolean values? Convert them too? if "count" in job_params.keys(): - job_params["count"] = int(job_params["count"]) + try: + job_params["count"] = int(job_params["count"]) + except: + raise InvalidArgumentValueError("Invalid count value. Count must be an integer.") # Make sure QIR jobs have an "arguments" parameter, even if it's empty if job_type == QIR_JOB: From 7e75a3118fb6a8a786b29ebdd1c04dc54d68e8c7 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 6 Jan 2023 16:13:50 -0800 Subject: [PATCH 46/65] Convert all numeric --job-params values from string to int or float --- src/quantum/azext_quantum/operations/job.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 5a64fc9108f..3dfd93c5fe5 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -192,6 +192,20 @@ def _has_completed(job): return job.status in ("Succeeded", "Failed", "Cancelled") +def _convert_numeric_params(job_params): + # The CLI framework passes all --job-params values as strings. This function + # attempts to convert numeric string values to their appropriate numeric types. + # Non-numeric string values and values that are already integers are unaffected. + for param in job_params: + try: + job_params[param] = int(job_params[param]) + except: + try: + job_params[param] = float(job_params[param]) + except: + pass + + def submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, project=None, job_name=None, shots=None, storage=None, no_build=False, job_params=None, target_capability=None, job_input_file=None, job_input_format=None, job_output_format=None, entry_point=None): @@ -341,6 +355,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati except: raise InvalidArgumentValueError("Invalid count value. Count must be an integer.") + # Convert all other numeric parameter values from string to int or float + _convert_numeric_params(job_params) + # Make sure QIR jobs have an "arguments" parameter, even if it's empty if job_type == QIR_JOB: if "arguments" not in job_params: From f500903a01040344f7f728901dc2e72e7611da15 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 9 Jan 2023 12:13:03 -0800 Subject: [PATCH 47/65] Add unit test for _convert_numeric_params --- src/quantum/azext_quantum/operations/job.py | 11 ++++++----- .../azext_quantum/tests/latest/test_quantum_jobs.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 3dfd93c5fe5..b1877c0f53a 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -197,13 +197,14 @@ def _convert_numeric_params(job_params): # attempts to convert numeric string values to their appropriate numeric types. # Non-numeric string values and values that are already integers are unaffected. for param in job_params: - try: - job_params[param] = int(job_params[param]) - except: + if isinstance(job_params[param], str): try: - job_params[param] = float(job_params[param]) + job_params[param] = int(job_params[param]) except: - pass + try: + job_params[param] = float(job_params[param]) + except: + pass def submit(cmd, program_args, resource_group_name, workspace_name, location, target_id, diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index bf9280ad59d..da9fc30947e 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -17,7 +17,7 @@ from ...commands import transform_output from ...operations.workspace import WorkspaceInfo, DEPLOYMENT_NAME_PREFIX from ...operations.target import TargetInfo -from ...operations.job import _generate_submit_args, _parse_blob_url, _validate_max_poll_wait_secs, build +from ...operations.job import _generate_submit_args, _parse_blob_url, _validate_max_poll_wait_secs, build, _convert_numeric_params TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..')) @@ -238,6 +238,17 @@ def test_validate_max_poll_wait_secs(self): except InvalidArgumentValueError as e: assert str(e) == "--max-poll-wait-secs parameter is not valid: foobar" + def test_convert_numeric_params(self): + # Show that it converts numeric strings, but doesn't modify params that are already numeric + test_job_params = {"integer1": "1", "float1.5": "1.5", "integer2": 2, "float2.5": 2.5, "integer3": "3", "float3.5": "3.5"} + _convert_numeric_params(test_job_params) + assert test_job_params == {"integer1": 1, "float1.5": 1.5, "integer2": 2, "float2.5": 2.5, "integer3": 3, "float3.5": 3.5} + + # Show that it doesn't modify non-numeric strings + test_job_params = {"string1": "string_value1", "string2": "string_value2", "string3": "string_value3"} + _convert_numeric_params(test_job_params) + assert test_job_params == {"string1": "string_value1", "string2": "string_value2", "string3": "string_value3"} + @live_only() def test_submit_qir(self): test_location = get_test_workspace_location() From f0070afc63fcc3601599a6a2c839f796b08621db Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 9 Jan 2023 17:55:03 -0800 Subject: [PATCH 48/65] Add support for tags and metadata --- src/quantum/azext_quantum/operations/job.py | 32 +++++++++++++++++-- .../tests/latest/test_quantum_jobs.py | 2 ++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index b1877c0f53a..1ad594b7b5d 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -276,8 +276,32 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if job_input_file is None: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) - # Extract the input-file-upload parameters from --job-parameters, then remove those parameters - # from job_params, since they should not be included in the inputParams property of job_details + # Extract "metadata" and "tags" from job_params, then remove those parameters from job_params, + # since they should not be included in the "inputParams" parameter of job_details. They are + # separate parameters of job_details. + # + # USAGE NOTE: The --job-params value needs to be a JSON string to specify "metadata". + metadata = None + tags = [] + if job_params is not None: + if "metadata" in job_params.keys(): + metadata = job_params["metadata"] + del job_params["metadata"] + if not isinstance(metadata, dict) and metadata is not None: + raise InvalidArgumentValueError('The "metadata" parameter is not valid.', + 'To specify "metadata", use a JSON string for the --job-params value.') + if "tags" in job_params.keys(): + tags = job_params["tags"] + del job_params["tags"] + if isinstance(tags, str): + tags = tags.split(',') + list_type = type([]) # "list" has been redefined as a function name, so "isinstance(tags, list)" doesn't work here + if not isinstance(tags, list_type): + raise InvalidArgumentValueError('The "tags" parameter is not valid.') + + # Extract "content_type" and "content_encoding" from --job-parameters, then remove those parameters + # from job_params, since they should not be included in the "inputParams" parameter of job_details. + # They are parameters of the upload_blob function. content_type = None content_encoding = None if job_params is not None: @@ -385,7 +409,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati 'output_data_format': job_output_format, 'inputParams': job_params, 'provider_id': provider_id, - 'target': target_info.target_id} + 'target': target_info.target_id, + 'metadata': metadata, + 'tags': tags} knack_logger.warning("Submitting job...") return client.create(job_id, job_details) diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index da9fc30947e..3e448ef96bb 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -249,6 +249,8 @@ def test_convert_numeric_params(self): _convert_numeric_params(test_job_params) assert test_job_params == {"string1": "string_value1", "string2": "string_value2", "string3": "string_value3"} + # >>>>>>>> Add a test that has tags and metadata + @live_only() def test_submit_qir(self): test_location = get_test_workspace_location() From e219d89f22f1dcb23e42b654a5cfe67284331a4c Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 12 Jan 2023 15:09:37 -0800 Subject: [PATCH 49/65] Revise and delete comments --- src/quantum/azext_quantum/operations/job.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 1ad594b7b5d..169c7d3acab 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -229,7 +229,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati Submit QIR bitcode, QIO problem JSON, or a pass-through job to run on Azure Quantum. """ - # Get workspace and target information + # Get workspace, target, and provider information ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) if ws_info is None: raise AzureInternalError("Failed to get workspace information.") @@ -373,7 +373,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if entry_point is not None: job_params["entryPoint"] = entry_point - # Convert "count" to an integer # <<<<< What about other numeric or Boolean values? Convert them too? + # Convert "count" to an integer if "count" in job_params.keys(): try: job_params["count"] = int(job_params["count"]) From afb3f4c9c6ba8b8f70b87d793068d7b25ef3e43c Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 13 Jan 2023 17:09:43 -0800 Subject: [PATCH 50/65] Accept camelCase blob upload params --- src/quantum/azext_quantum/operations/job.py | 9 ++++++++- .../tests/latest/test_quantum_targets.py | 14 +++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 169c7d3acab..2b100f44dee 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -302,15 +302,22 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # Extract "content_type" and "content_encoding" from --job-parameters, then remove those parameters # from job_params, since they should not be included in the "inputParams" parameter of job_details. # They are parameters of the upload_blob function. + # These param names are accepted in two formats: See comments below. content_type = None content_encoding = None if job_params is not None: - if "content_type" in job_params.keys(): + if "content_type" in job_params.keys(): # Names are often in in snake_case in our Jupyter notebooks... content_type = job_params["content_type"] del job_params["content_type"] + if "contentType" in job_params.keys(): # ...however, the params that go into inputParams are generally in camelCase. + content_type = job_params["contentType"] + del job_params["contentType"] if "content_encoding" in job_params.keys(): content_encoding = job_params["content_encoding"] del job_params["content_encoding"] + if "contentEncoding" in job_params.keys(): + content_encoding = job_params["contentEncoding"] + del job_params["contentEncoding"] # Prepare for input file upload according to job type if job_type == QIO_JOB: diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py b/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py index e350a96ae32..02b1754aa85 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py @@ -7,10 +7,11 @@ import pytest import unittest -from azure.cli.testsdk.scenario_tests import AllowLargeResponse +from azure.cli.testsdk.scenario_tests import AllowLargeResponse, live_only from azure.cli.testsdk import (ScenarioTest, ResourceGroupPreparer) from .utils import get_test_resource_group, get_test_workspace, get_test_workspace_location, issue_cmd_with_param_missing +from ...operations.target import get_provider, TargetInfo TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..')) @@ -52,3 +53,14 @@ def test_targets(self): def test_target_errors(self): self.cmd(f'az quantum target clear') issue_cmd_with_param_missing(self, "az quantum target set", "az quantum target set -t target-id\nSelect a default when submitting jobs to Azure Quantum.") + + @live_only() + def test_get_provider(self): + test_location = get_test_workspace_location() + test_workspace = get_test_workspace() + test_resource_group = get_test_resource_group() + # test_target = get_test_target()) + # test_provider = get_test_provider + # returned_provider = get_provider(self.cmd, test_target, test_resource_group, test_workspace, test_location) + # assert returned_provider == test_provider + # >>>>> TODO: Finish this test From f8185ea85ba7654bdf74b1251e07a01ca531f551 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 23 Jan 2023 16:14:06 -0800 Subject: [PATCH 51/65] Add Quil and Qiskit tests --- src/quantum/azext_quantum/_help.py | 7 +- src/quantum/azext_quantum/_params.py | 8 +- src/quantum/azext_quantum/operations/job.py | 53 +- .../latest/input_data/QIO-Problem-2.json | 18 + .../Qiskit-3-qubit-GHZ-circuit.json | 1 + .../tests/latest/input_data/QuantumRNG.csproj | 4 +- .../tests/latest/input_data/bell-state.quil | 7 + .../latest/recordings/test_get_provider.yaml | 1461 ++++++++ .../tests/latest/recordings/test_submit.yaml | 3326 +++++++++++++++++ .../tests/latest/test_quantum_jobs.py | 75 +- .../tests/latest/test_quantum_targets.py | 29 +- .../azext_quantum/tests/latest/utils.py | 15 +- 12 files changed, 4916 insertions(+), 88 deletions(-) create mode 100644 src/quantum/azext_quantum/tests/latest/input_data/QIO-Problem-2.json create mode 100644 src/quantum/azext_quantum/tests/latest/input_data/Qiskit-3-qubit-GHZ-circuit.json create mode 100644 src/quantum/azext_quantum/tests/latest/input_data/bell-state.quil create mode 100644 src/quantum/azext_quantum/tests/latest/recordings/test_get_provider.yaml create mode 100644 src/quantum/azext_quantum/tests/latest/recordings/test_submit.yaml diff --git a/src/quantum/azext_quantum/_help.py b/src/quantum/azext_quantum/_help.py index 941868ef7d6..7fee9a6b254 100644 --- a/src/quantum/azext_quantum/_help.py +++ b/src/quantum/azext_quantum/_help.py @@ -99,10 +99,11 @@ text: |- az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation -t MyTarget \\ --target-capability MyTargetCapability - - name: Submit QIR bitcode from the current folder. + - name: Submit QIR bitcode from a file in the current folder. text: |- - az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation \\ - -t MyTarget --job-name MyJob --job-input-format qir.v1 --entry-point MyQirEntryPoint + az quantum job submit -g MyResourceGroup -w MyWorkspace -l MyLocation -t MyTarget \\ + --job-name MyJob --job-input-format qir.v1 --job-input-file MyQirBitcode.bc \\ + --entry-point MyQirEntryPoint """ helps['quantum job wait'] = """ diff --git a/src/quantum/azext_quantum/_params.py b/src/quantum/azext_quantum/_params.py index 194494395a0..80e6fdf266c 100644 --- a/src/quantum/azext_quantum/_params.py +++ b/src/quantum/azext_quantum/_params.py @@ -52,10 +52,10 @@ def load_arguments(self, _): provider_sku_list_type = CLIArgumentType(options_list=['--provider-sku-list', '-r'], help='Comma separated list of Provider/SKU pairs. Separate the Provider and SKU with a slash. Enclose the entire list in quotes. Values from `az quantum offerings list -l -o table`') auto_accept_type = CLIArgumentType(help='If specified, provider terms are accepted without an interactive Y/N prompt.') autoadd_only_type = CLIArgumentType(help='If specified, only the plans flagged "autoAdd" are displayed.') - job_input_file_type = CLIArgumentType(help='The location of the input file to submit. Path defaults to current folder. Default filename extension is based on --job-input-type') - job_input_format_type = CLIArgumentType(help='The format of the file to submit. Defaults to Q# project.') - job_output_format_type = CLIArgumentType(help='The expected job output format.') - entry_point_type = CLIArgumentType(help='The entry point for the QIR program or circuit. Required for QIR. Ignored for Q# projects.') + job_input_file_type = CLIArgumentType(help='The location of the input file to submit. Required for QIR, QIO, and pass-through jobs. Ignored on Q# jobs.') + job_input_format_type = CLIArgumentType(help='The format of the file to submit. Omit this parameter on Q# jobs.') + job_output_format_type = CLIArgumentType(help='The expected job output format. Ignored on Q# jobs.') + entry_point_type = CLIArgumentType(help='The entry point for the QIR program or circuit. Required for QIR. Ignored on Q# jobs.') with self.argument_context('quantum workspace') as c: c.argument('workspace_name', workspace_name_type) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 2b100f44dee..bc0b236575b 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -242,37 +242,22 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # Identify the type of job being submitted lc_job_input_format = job_input_format.lower() - if "qir.v" in lc_job_input_format: # QCI uses "qir.v1", but Rigetti uses "rigetti.qir.v1" and Quantinuum uses "honeywell.qir.v1" + if "qir.v" in lc_job_input_format: job_type = QIR_JOB elif lc_job_input_format == "microsoft.qio.v2": job_type = QIO_JOB else: job_type = PASS_THROUGH_JOB - # If output format is not specified, supply a default for QIR or QIO jobs # <<<<< Is this out-of-scope? + # If output format is not specified, supply a default for QIR or QIO jobs if job_output_format is None: if job_type == QIR_JOB: - job_output_format = "microsoft.quantum-results.v1" # <<<<< This works for QCI, but is it OK for Rigetti and Quantinuum QIR? <<<<< + job_output_format = "microsoft.quantum-results.v1" elif job_type == QIO_JOB: job_output_format = "microsoft.qio-results.v2" else: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) - # Look for an input file based on job_input_format - if job_input_file is None: - if job_type == QIR_JOB: - input_file_extension = ".bc" - elif job_type == QIO_JOB: - input_file_extension = ".json" - else: - raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) - - path = os.path.abspath(os.curdir) - for file_name in os.listdir(path): - if file_name.endswith(input_file_extension): - job_input_file = os.path.join(path, file_name) - break - if job_input_file is None: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) @@ -280,7 +265,8 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # since they should not be included in the "inputParams" parameter of job_details. They are # separate parameters of job_details. # - # USAGE NOTE: The --job-params value needs to be a JSON string to specify "metadata". + # USAGE NOTE: To specify "metadata", the --job-params value needs to be entered as a JSON string or file. + # metadata = None tags = [] if job_params is not None: @@ -299,19 +285,25 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if not isinstance(tags, list_type): raise InvalidArgumentValueError('The "tags" parameter is not valid.') - # Extract "content_type" and "content_encoding" from --job-parameters, then remove those parameters - # from job_params, since they should not be included in the "inputParams" parameter of job_details. - # They are parameters of the upload_blob function. - # These param names are accepted in two formats: See comments below. + # Extract content type and content encoding from --job-parameters, then remove those parameters from job_params, since + # they should not be included in the "inputParams" parameter of job_details. Content type and content encoding are + # parameters of the upload_blob function. These parameters are accepted in three case-formats: kebab-case, snake_case, + # and camelCase. (See comments below.) content_type = None content_encoding = None if job_params is not None: - if "content_type" in job_params.keys(): # Names are often in in snake_case in our Jupyter notebooks... + if "content-type" in job_params.keys(): # Parameter names in the CLI are commonly in kebab-case (hyphenated)... + content_type = job_params["content-type"] + del job_params["content-type"] + if "content_type" in job_params.keys(): # ...however names are often in in snake_case in our Jupyter notebooks... content_type = job_params["content_type"] del job_params["content_type"] - if "contentType" in job_params.keys(): # ...however, the params that go into inputParams are generally in camelCase. + if "contentType" in job_params.keys(): # ...but the params that go into inputParams are generally in camelCase. content_type = job_params["contentType"] del job_params["contentType"] + if "content-encoding" in job_params.keys(): + content_encoding = job_params["content-encoding"] + del job_params["content-encoding"] if "content_encoding" in job_params.keys(): content_encoding = job_params["content_encoding"] del job_params["content_encoding"] @@ -361,8 +353,15 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati knack_logger.warning("Uploading input data...") try: blob_uri = upload_blob(container_client, blob_name, content_type, content_encoding, blob_data, False) - except: - raise AzureResponseError("Upload failed. Please try submitting the job again.") + except Exception as e: + # Unexplained behavior: + # QIR bitcode input and QIO (gzip) input data get UnicodeDecodeError on jobs run in tests using + # "azdev test --live", but the same commands are successful when run interactively. + # See commented-out tests in test_submit in test_quantum_jobs.py + error_msg = f"Input file upload failed.\nError type: {type(e)}" + if isinstance(e, UnicodeDecodeError): + error_msg += f"\nReason: {e.reason}" + raise AzureResponseError(error_msg) from e start_of_blob_name = blob_uri.find(blob_name) container_uri = blob_uri[0:start_of_blob_name - 1] diff --git a/src/quantum/azext_quantum/tests/latest/input_data/QIO-Problem-2.json b/src/quantum/azext_quantum/tests/latest/input_data/QIO-Problem-2.json new file mode 100644 index 00000000000..84858120d71 --- /dev/null +++ b/src/quantum/azext_quantum/tests/latest/input_data/QIO-Problem-2.json @@ -0,0 +1,18 @@ +{ + "metadata": { + "name": "QIO Problem 02 v-wjones" + }, + "cost_function": { + "version": "1.0", + "type": "ising", + "terms": [ + {"c": -9, "ids": [0]}, + {"c": -3, "ids": [1, 0]}, + {"c": 5, "ids": [2, 0]}, + {"c": 9, "ids": [2, 1]}, + {"c": 2, "ids": [3, 0]}, + {"c": -4, "ids": [3, 1]}, + {"c": 4, "ids": [3, 2]} + ] + } +} \ No newline at end of file diff --git a/src/quantum/azext_quantum/tests/latest/input_data/Qiskit-3-qubit-GHZ-circuit.json b/src/quantum/azext_quantum/tests/latest/input_data/Qiskit-3-qubit-GHZ-circuit.json new file mode 100644 index 00000000000..1e740286355 --- /dev/null +++ b/src/quantum/azext_quantum/tests/latest/input_data/Qiskit-3-qubit-GHZ-circuit.json @@ -0,0 +1 @@ +{"gateset": "qis", "qubits": 3, "circuit": [{"gate": "h", "targets": [0]}, {"gate": "x", "targets": [1], "controls": [0]}, {"gate": "x", "targets": [2], "controls": [1]}]} \ No newline at end of file diff --git a/src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj b/src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj index fff8f29d8b3..4b048a8363c 100644 --- a/src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj +++ b/src/quantum/azext_quantum/tests/latest/input_data/QuantumRNG.csproj @@ -1,7 +1,7 @@ - + Exe - netcoreapp3.1 + net6.0 ionq.qpu \ No newline at end of file diff --git a/src/quantum/azext_quantum/tests/latest/input_data/bell-state.quil b/src/quantum/azext_quantum/tests/latest/input_data/bell-state.quil new file mode 100644 index 00000000000..70706838752 --- /dev/null +++ b/src/quantum/azext_quantum/tests/latest/input_data/bell-state.quil @@ -0,0 +1,7 @@ +DECLARE ro BIT[2] + +H 0 +CNOT 0 1 + +MEASURE 0 ro[0] +MEASURE 1 ro[1] \ No newline at end of file diff --git a/src/quantum/azext_quantum/tests/latest/recordings/test_get_provider.yaml b/src/quantum/azext_quantum/tests/latest/recordings/test_get_provider.yaml new file mode 100644 index 00000000000..fd2a9092b94 --- /dev/null +++ b/src/quantum/azext_quantum/tests/latest/recordings/test_get_provider.yaml @@ -0,0 +1,1461 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Quantum/locations/eastus/offerings?api-version=2022-01-10-preview + response: + body: + string: "{\"value\":[{\"id\":\"1qbit\",\"name\":\"1Qloud Optimization Platform\",\"properties\":{\"description\":\"1QBit + 1Qloud Optimization Platform with Quantum Inspired Solutions\",\"providerType\":\"qio\",\"company\":\"1QBit\",\"managedApplication\":{\"publisherId\":\"1qbinformationtechnologies1580939206424\",\"offerId\":\"1qbit-1qloud-optimization-aq\"},\"targets\":[{\"id\":\"1qbit.tabu\",\"name\":\"1QBit + Quadratic Tabu Solver\",\"description\":\"An iterative heuristic algorithm + that uses local search techniques to solve a problem\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"1qbit.pathrelinking\",\"name\":\"1QBit + Quadratic Path-Relinking Solver\",\"description\":\"The path-relinking algorithm + is a heuristic algorithm that uses the tabu search as a subroutine to solve + a QUBO problem\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"1qbit.pticm\",\"name\":\"1QBit + Quadratic Parallel Tempering Isoenergetic Cluster Moves Solver\",\"description\":\"The + parallel tempering with isoenergetic cluster moves (PTICM) solver is a Monte + Carlo approach to solving QUBO problems\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"1qbit-internal-free-plan\",\"version\":\"1.0.3\",\"name\":\"1QBit + No Charge Plan\",\"description\":\"1QBit plan with no charge for specific + customer arrangements\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"Free + for select customers\"}]},{\"id\":\"1qbit-fixed-monthly-202012\",\"version\":\"1.0.3\",\"name\":\"Fixed + Monthly Plan\",\"description\":\"This plan provides access to all 1QBit quantum-inspired + optimization solvers with a flat monthly fee\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$7500 + USD per month\"}]},{\"id\":\"1qbit-pay-as-you-go-20210428\",\"version\":\"1.0.3\",\"name\":\"Pay + As You Go by CPU Usage\",\"description\":\"This plan provides access to all + 1QBit quantum-inspired optimization solvers with a pay as you go pricing\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$0.075 + per minute; rounded up to nearest second, with a minimum 1-second charge per + solve request\"}]}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"ionq\",\"name\":\"IonQ\",\"properties\":{\"description\":\"IonQ\u2019s + trapped ion quantum computers perform calculations by manipulating charged + atoms of Ytterbium held in a vacuum with lasers.\",\"providerType\":\"qe\",\"company\":\"IonQ\",\"managedApplication\":{\"publisherId\":\"ionqinc1582730893633\",\"offerId\":\"ionq-aq\"},\"targets\":[{\"id\":\"ionq.simulator\",\"name\":\"Trapped + Ion Quantum Computer Simulator\",\"description\":\"GPU-accelerated idealized + simulator supporting up to 29 qubits, using the same gates IonQ provides on + its quantum computers. No errors are modeled at present.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu\",\"name\":\"Trapped + Ion Quantum Computer\",\"description\":\"IonQ's quantum computer is dynamically + reconfigurable in software to use up to 11 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu.aria-1\",\"name\":\"Aria + 1\",\"description\":\"IonQ's Aria 1 quantum computer is dynamically reconfigurable + in software to use up to 23 qubits. All qubits are fully connected, meaning + you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.simulator-preview\",\"name\":\"Trapped + Ion Quantum Computer Simulator Preview\",\"description\":\"GPU-accelerated + idealized simulator supporting up to 29 qubits, using the same gates IonQ + provides on its quantum computers. No errors are modeled at present.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu-preview\",\"name\":\"Harmony + Preview\",\"description\":\"IonQ's Harmony quantum computer is dynamically + reconfigurable in software to use up to 11 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu.aria-1-preview\",\"name\":\"Aria + 1 Preview\",\"description\":\"IonQ's Aria 1 quantum computer is dynamically + reconfigurable in software to use up to 23 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"pay-as-you-go-cred\",\"version\":\"0.0.5\",\"name\":\"Azure + Quantum Credits\",\"description\":\"The Azure Quantum Credits program provides + sponsored access to IonQ hardware through Azure. You will not be charged for + usage created under the credits program.\",\"autoAdd\":true,\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"quotaDimensions\":[{\"id\":\"qgs\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Aria Trapped + Ion QC (23 qubits)
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"$500 worth + of IonQ compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.\"}]},{\"id\":\"pay-as-you-go\",\"version\":\"0.0.5\",\"name\":\"Pay + As You Go\",\"description\":\"A la carte access based on resource requirements + and usage.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"No limit\"},{\"id\":\"price\",\"value\":\"$ + 3,000.00 USD / hour (est)
See documentation for details\"}]},{\"id\":\"committed-subscription-2\",\"version\":\"0.0.5\",\"name\":\"Subscription\",\"description\":\"Committed + access to all of IonQ's quantum computers\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:partnerships@ionq.co\",\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Aria Trapped + Ion QC (23 qubits)
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$ + 25,000.00 USD / month
See documentation for details\"}]},{\"id\":\"private-preview-free\",\"version\":\"0.0.5\",\"name\":\"QIR + Private Preview Free\",\"description\":\"Submit QIR jobs to IonQ quantum platform.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + QIR job execution\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"N/A\"}]},{\"id\":\"preview-internal\",\"version\":\"0.0.5\",\"name\":\"Internal + Preview\",\"description\":\"Internal preview with zero cost.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\",\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Internal Preview\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"N/A\"}]},{\"id\":\"aq-internal-testing\",\"version\":\"0.0.1\",\"name\":\"Microsoft + Internal Testing\",\"description\":\"You're testing, so it's free! As in beer.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\",\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Harmony Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"Free\"}]}],\"quotaDimensions\":[{\"id\":\"qgs\",\"scope\":\"Subscription\",\"quota\":16666667,\"period\":\"Infinite\",\"name\":\"QPU + Credit\",\"description\":\"Credited resource usage against your account. See + IonQ documentation for more information: https://aka.ms/AQ/IonQ/ProviderDocumentation.\",\"unit\":\"qubit-gate-shot\",\"unitPlural\":\"qubit-gate-shots\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Limits\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"Microsoft\",\"name\":\"Microsoft + QIO\",\"properties\":{\"description\":\"Ground-breaking optimization algorithms + inspired by decades of quantum research.\",\"providerType\":\"qio\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.tabu.cpu\",\"name\":\"microsoft.tabu.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.qmc.cpu\",\"name\":\"microsoft.qmc.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.tabu-parameterfree.cpu\",\"name\":\"microsoft.tabu-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.simulatedannealing.cpu\",\"name\":\"microsoft.simulatedannealing.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.simulatedannealing-parameterfree.cpu\",\"name\":\"microsoft.simulatedannealing-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.paralleltempering.cpu\",\"name\":\"microsoft.paralleltempering.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.paralleltempering-parameterfree.cpu\",\"name\":\"microsoft.paralleltempering-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.populationannealing.cpu\",\"name\":\"microsoft.populationannealing.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.substochasticmontecarlo.cpu\",\"name\":\"microsoft.substochasticmontecarlo.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"name\":\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.populationannealing-parameterfree.cpu\",\"name\":\"microsoft.populationannealing-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"Basic\",\"version\":\"1.0\",\"name\":\"Private + Preview\",\"description\":\"Free Private Preview access through February 15 + 2020\",\"autoAdd\":false,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"microsoft.populationannealing-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 5 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"CPU based: 5 hours / month\"},{\"id\":\"price\",\"value\":\"$ + 0\"}]},{\"id\":\"DZH3178M639F\",\"version\":\"1.0\",\"name\":\"Learn & Develop\",\"description\":\"Learn + and develop with Optimization solutions.\",\"autoAdd\":true,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":20},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 5 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"CPU based: 20 hours / month\"},{\"id\":\"price\",\"value\":\"Pay + as you go
1 free hour included

See + pricing sheet\"}]},{\"id\":\"DZH318RV7MW4\",\"version\":\"1.0\",\"name\":\"Scale\",\"description\":\"Deploy + world-class Optimization solutions.\",\"autoAdd\":false,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":1000},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":100}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 100 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"Up to 50,000 hours / month\"},{\"id\":\"price\",\"value\":\"Pay + as you go
1 free hour included

See + pricing sheet\"}]},{\"id\":\"EarlyAccess\",\"version\":\"1.0\",\"name\":\"Early + Access\",\"description\":\"Help us test new capabilities in our Microsoft + Optimization provider. This SKU is available to a select group of users and + limited to targets that we are currently running an Early Access test for.\",\"autoAdd\":false,\"targets\":[],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":10},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"No + available targets.\"},{\"id\":\"quota\",\"value\":\"CPU based: 10 hours / + month\"},{\"id\":\"price\",\"value\":\"$ 0\"}]}],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":5,\"period\":\"Monthly\",\"name\":\"CPU + Solver Hours [Workspace]\",\"description\":\"The amount of CPU solver time + you may use per month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"CPU + Solver Hours [Subscription]\",\"description\":\"The amount of CPU solver time + you may use per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":5}],\"pricingDimensions\":[{\"id\":\"targets\",\"name\":\"Targets + available\"},{\"id\":\"perf\",\"name\":\"Performance\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Price + per month\"}]}},{\"id\":\"microsoft-qc\",\"name\":\"Microsoft Quantum Computing\",\"properties\":{\"description\":\"Prepare + for fault-tolerant quantum computing with Microsoft specific tools and services, + including the Azure Quantum Resource Estimator.\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.estimator\",\"name\":\"Resource + Estimator\",\"acceptedDataFormats\":[\"microsoft.qir.v1\",\"qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"learn-and-develop\",\"version\":\"1.0\",\"name\":\"Learn + & Develop\",\"description\":\"Free plan including access to hosted notebooks + with pre-configured support for Q#, Qiskit and Cirq, noisy simulator and Azure + Quantum Resource Estimator.\",\"autoAdd\":true,\"targets\":[\"microsoft.estimator\"],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Resource + Estimator

Designed specifically for scaled quantum systems, Azure + Quantum Resource Estimator provides estimates for the number of physical qubits + and runtime required to execute quantum applications on post-NISQ, fault-tolerant + systems.\"},{\"id\":\"quota\",\"value\":\"Up to 10 concurrent jobs.\"},{\"id\":\"price\",\"value\":\"Free + usage.\"}]}],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\",\"quota\":10}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"Microsoft.FleetManagement\",\"name\":\"Microsoft + Fleet Management Solution\",\"properties\":{\"description\":\"(Preview) Leverage + Azure Quantum's advanced optimization algorithms to solve fleet management + problems.\",\"providerType\":\"qio\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.fleetmanagement\",\"name\":\"microsoft.fleetmanagement\",\"acceptedDataFormats\":[\"microsoft.fleetmanagement.v1\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"Basic\",\"version\":\"1.0\",\"name\":\"Private + Preview\",\"description\":\"Private preview fleet management SKU.\",\"autoAdd\":false,\"targets\":[\"microsoft.fleetManagement\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}]}],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":20,\"period\":\"Monthly\",\"name\":\"Job + Hours [Workspace]\",\"description\":\"The amount of job time you may use per + month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Job + Hours [Subscription]\",\"description\":\"The amount of job time you may use + per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":5}]}},{\"id\":\"Microsoft.Simulator\",\"name\":\"Microsoft + Simulation Tools\",\"properties\":{\"description\":\"Microsoft Simulation + Tools.\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.simulator.resources-estimator\",\"name\":\"Quantum + Resources Estimator\",\"acceptedDataFormats\":[\"microsoft.qir.v1\",\"qir.v1\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"resources-estimator-preview\",\"version\":\"1.0\",\"name\":\"Resource + Estimation Private Preview\",\"description\":\"Private preview plan for resource + estimation. Provider and target names may change upon public preview.\",\"autoAdd\":false,\"targets\":[\"microsoft.simulator.resources-estimator\"],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\"}]}],\"quotaDimensions\":[{\"id\":\"simulator_job_hours\",\"scope\":\"Workspace\",\"quota\":20,\"period\":\"Monthly\",\"name\":\"Simulator + Hours [Workspace]\",\"description\":\"The amount of simulator time you may + use per month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"simulator_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Simulator + Hours [Subscription]\",\"description\":\"The amount of simulator time you + may use per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_simulator_jobs\",\"scope\":\"Workspace\",\"quota\":5},{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\",\"quota\":10}]}},{\"id\":\"Microsoft.Test\",\"name\":\"Microsoft + Test Provider\",\"properties\":{\"description\":\"Microsoft Test Provider\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"microsoft_qio\",\"offerId\":\"samplepartner-aq-preview\"},\"targets\":[{\"id\":\"echo-rigetti\",\"name\":\"echo-rigetti\",\"acceptedDataFormats\":[\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-quantinuum\",\"name\":\"echo-quantinuum\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-qci\",\"name\":\"echo-qci\",\"acceptedDataFormats\":[\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-output\",\"name\":\"echo-output\",\"acceptedDataFormats\":[\"microsoft.quantum-log.v1.1\",\"microsoft.quantum-log.v2.1\",\"microsoft.quantum-log.v1\",\"microsoft.quantum-log.v2\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"sample-plan-3\",\"version\":\"1.0.4\",\"name\":\"Standard\",\"description\":\"Standard + services\",\"autoAdd\":false,\"targets\":[\"echo-rigetti\",\"echo-quantinuum\",\"echo-qci\",\"echo-output\"],\"pricingDetails\":[{\"id\":\"price\",\"value\":\"Free\"}]}],\"pricingDimensions\":[{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"qci\",\"name\":\"Quantum + Circuits, Inc.\",\"properties\":{\"description\":\"Superconducting Circuits + Quantum Computing Systems\",\"providerType\":\"qe\",\"company\":\"Quantum + Circuits, Inc.\",\"managedApplication\":{\"publisherId\":\"quantumcircuitsinc1598045891596\",\"offerId\":\"qci-aq\"},\"targets\":[{\"id\":\"qci.machine1\",\"name\":\"Machine + 1\",\"description\":\"8-qubit quantum computing system with real-time control + flow capability.\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"qci.simulator\",\"name\":\"AquSim\",\"description\":\"8-qubit + noise-free simulator.\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"qci.simulator.noisy\",\"name\":\"AquSim-N\",\"description\":\"8-qubit + simulator that incorporates QCI's gate and measurement performance\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"qci-syspreview\",\"version\":\"0.1.0\",\"name\":\"System + Preview\",\"description\":\"A metered pricing preview of QCI's Systems and + Simulators\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Integration + testing plan for Microsoft\"},{\"id\":\"quota\",\"value\":\"1000 jobs per + month\"},{\"id\":\"price\",\"value\":\"\"}]},{\"id\":\"qci-syspreview-free\",\"version\":\"0.1.0\",\"name\":\"System + Preview Free\",\"description\":\"A free preview of QCI's Systems and Simulators\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Integration + testing plan for Microsoft\"},{\"id\":\"quota\",\"value\":\"Unlimited jobs\"},{\"id\":\"price\",\"value\":\"\"}]},{\"id\":\"qci-freepreview\",\"version\":\"0.1.0\",\"name\":\"System + Preview (Free)\",\"description\":\"A free preview of QCI's simulators and + quantum systems.\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Machine + 1 Quantum System and the AquSim Quantum Simulator\"},{\"id\":\"quota\",\"value\":\"1000 + jobs per month\"},{\"id\":\"price\",\"value\":\"\"}]}],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Job + Count\",\"description\":\"Number of jobs you can run in a month.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"quantinuum\",\"name\":\"Quantinuum\",\"properties\":{\"description\":\"Access + to Quantinuum trapped-ion systems\",\"providerType\":\"qe\",\"company\":\"Quantinuum\",\"managedApplication\":{\"publisherId\":\"quantinuumllc1640113159771\",\"offerId\":\"quantinuum-aq\"},\"targets\":[{\"id\":\"quantinuum.hqs-lt-s1\",\"name\":\"Quantinuum + H1-1\",\"description\":\"Quantinuum H1-1, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-1\",\"name\":\"Quantinuum + H1-1\",\"description\":\"Quantinuum H1-1, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2\",\"name\":\"Quantinuum + H1-2\",\"description\":\"Quantinuum H1-2, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-2\",\"name\":\"Quantinuum + H1-2\",\"description\":\"Quantinuum H1-2, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt\",\"name\":\"Quantinuum + System Model: H1 Family\",\"description\":\"Quantinuum System Model H1 Family, + Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1\",\"name\":\"Quantinuum + System Model: H1 Family\",\"description\":\"Quantinuum System Model H1 Family, + Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s1-apival\",\"name\":\"Quantinuum + H1-1 Syntax Checker\",\"description\":\"Quantinuum H1-1 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1sc\",\"name\":\"Quantinuum + H1-1 Syntax Checker\",\"description\":\"Quantinuum H1-1 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2-apival\",\"name\":\"Quantinuum + H1-2 Syntax Checker\",\"description\":\"Quantinuum H1-2 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2sc\",\"name\":\"Quantinuum + H1-2 Syntax Checker\",\"description\":\"Quantinuum H1-2 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s1-sim\",\"name\":\"Quantinuum + H1-1 Emulator\",\"description\":\"Quantinuum H1-1 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1e\",\"name\":\"Quantinuum + H1-1 Emulator\",\"description\":\"Quantinuum H1-1 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2-sim\",\"name\":\"Quantinuum + H1-2 Emulator\",\"description\":\"Quantinuum H1-2 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2e\",\"name\":\"Quantinuum + H1-2 Emulator\",\"description\":\"Quantinuum H1-2 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1sc-preview\",\"name\":\"Quantinuum + H1-1 Syntax Checker Preview\",\"description\":\"Quantinuum H1-1 Syntax Checker + Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2sc-preview\",\"name\":\"Quantinuum + H1-2 Syntax Checker Preview\",\"description\":\"Quantinuum H1-2 Syntax Checker + Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1e-preview\",\"name\":\"Quantinuum + H1-1 Emulator Preview\",\"description\":\"Quantinuum H1-1 Emulator Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2e-preview\",\"name\":\"Quantinuum + H1-2 Emulator Preview\",\"description\":\"Quantinuum H1-2 Emulator Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-1-preview\",\"name\":\"Quantinuum + H1-1 Preview\",\"description\":\"Quantinuum H1-1 Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-2-preview\",\"name\":\"Quantinuum + H1-2 Preview\",\"description\":\"Quantinuum H1-2 Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"credits1\",\"version\":\"1.0.0\",\"name\":\"Azure + Quantum Credits\",\"description\":\"The Azure Quantum Credits program provides + sponsored access to Quantinuum hardware through Azure. You will not be charged + for usage created under the credits program, up to the limit of your credit + grant.\",\"autoAdd\":true,\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"System + Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum + System Model H1, Powered by Honeywell\"},{\"id\":\"limits\",\"value\":\"Up + to $500 of Quantinuum compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.\"}]},{\"id\":\"premium1\",\"version\":\"1.0.0\",\"name\":\"Premium\",\"description\":\"Monthly + subscription plan with 17K Quantinuum H-System Quantum Credits (HQCs) / month, + available through queue\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:QuantinuumAzureQuantumSupport@Quantinuum.com\",\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"17K H-System + Quantum Credits (HQCs) / month\"},{\"id\":\"price\",\"value\":\"$ 175,000 + USD / Month\"}]},{\"id\":\"standard1\",\"version\":\"1.0.0\",\"name\":\"Standard\",\"description\":\"Monthly + subscription plan with 10K Quantinuum H-System quantum credits (HQCs) / month, + available through queue\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:QuantinuumAzureQuantumSupport@Quantinuum.com\",\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"10K H-System + Quantum Credits (HQCs) / month\"},{\"id\":\"price\",\"value\":\"$ 125,000 + USD / Month\"}]},{\"id\":\"test1\",\"version\":\"1.0.0\",\"name\":\"Partner + Access\",\"description\":\"Charge-free access to Quantinuum System Model H1 + for Azure integration verification\",\"autoAdd\":false,\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\",\"quantinuum.sim.h1-1sc-preview\",\"quantinuum.sim.h1-2sc-preview\",\"quantinuum.sim.h1-1e-preview\",\"quantinuum.sim.h1-2e-preview\",\"quantinuum.qpu.h1-1-preview\",\"quantinuum.qpu.h1-2-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"No limit for + integration testing\"},{\"id\":\"price\",\"value\":\"Free for validation\"}]}],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\",\"quota\":40,\"period\":\"Infinite\",\"name\":\"H-System + Quantum Credit (HQC)\",\"description\":\"H-System Quantum Credits (HQCs) are + used to calculate the cost of a job. See Quantinuum documentation for more + information.\",\"unit\":\"HQC\",\"unitPlural\":\"HQC's\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\",\"quota\":400,\"period\":\"Infinite\",\"name\":\"Emulator + HQCs (eHQC)\",\"description\":\"Quantinuum Emulator H-System Quantum Credits + (eHQCs) are used for submission to the emulator.\",\"unit\":\"EHQC\",\"unitPlural\":\"EHQC's\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"limits\",\"name\":\"Limits\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"rigetti\",\"name\":\"Rigetti + Quantum\",\"properties\":{\"description\":\"Run quantum programs on Rigetti's + superconducting qubit-based quantum processors.\",\"providerType\":\"qe\",\"company\":\"Rigetti + Computing\",\"managedApplication\":{\"publisherId\":\"rigetticoinc1644276861431\",\"offerId\":\"rigetti-aq\"},\"targets\":[{\"id\":\"rigetti.sim.qvm\",\"name\":\"QVM\",\"description\":\"Simulate + Quil and QIR programs on the open-source Quantum Virtual Machine.\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-11\",\"name\":\"Aspen-11\",\"description\":\"A + 40-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-m-2\",\"name\":\"Aspen-M-2\",\"description\":\"An + 80-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-m-3\",\"name\":\"Aspen-M-3\",\"description\":\"An + 80-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"rigetti-private-beta-metered\",\"version\":\"0.0.0\",\"name\":\"Metered + Private Preview\",\"description\":\"Limited-time free access to Rigetti quantum + computers with the ability to see your utilization.\",\"autoAdd\":false,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"This plan has no quota.\"},{\"id\":\"price\",\"value\":\"This + plan is free.\"}]},{\"id\":\"rigetti-pay-as-you-go\",\"version\":\"0.0.0\",\"name\":\"Pay + As You Go\",\"description\":\"Pay-as-you-go access to Rigetti quantum computers.\",\"autoAdd\":false,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"This plan has no quota.\"},{\"id\":\"price\",\"value\":\"$0.02 + per 10 milliseconds (rounded up) of QPU execution time.\"}]},{\"id\":\"azure-quantum-credits\",\"version\":\"0.0.0\",\"name\":\"Azure + Quantum Credits\",\"description\":\"Pay with Azure credits for access to Rigetti + quantum computers.\",\"autoAdd\":true,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"quotaDimensions\":[{\"id\":\"provider-credit\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"$500 worth of Rigetti + compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.
Credits consumed on the base + of $0.02 (credits) per 10 milliseconds (rounded up) of QPU execution time.\"}]}],\"quotaDimensions\":[{\"id\":\"provider-credit\",\"scope\":\"Subscription\",\"quota\":25000,\"period\":\"Infinite\",\"name\":\"QPU + Credits\",\"description\":\"One credit covers 10 milliseconds of QPU execution + time, which normally costs $0.02.\",\"unit\":\"credit\",\"unitPlural\":\"credits\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"toshiba\",\"name\":\"SQBM+ + Cloud on Azure Quantum\",\"properties\":{\"description\":\"A GPU-powered ISING + machine featuring the Simulated Bifurcation algorithm inspired by Toshiba's + research on quantum computing.\",\"providerType\":\"qio\",\"company\":\"Toshiba + Digital Solutions Corporation\",\"managedApplication\":{\"publisherId\":\"2812187\",\"offerId\":\"toshiba-aq\"},\"targets\":[{\"id\":\"toshiba.sbm.ising\",\"name\":\"Ising + solver\",\"description\":\"Originated from research on quantum bifurcation + machines, the SQBM+ is a practical and ready-to-use ISING machine that solves + large-scale \\\"combinatorial optimization problems\\\" at high speed.\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"toshiba-solutionseconds\",\"version\":\"1.0.1\",\"name\":\"Pay + As You Go\",\"description\":\"This is the only plan for using SQBM+ in Azure + Quantum Private Preview.\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"No + limit\"},{\"id\":\"price\",\"value\":\"This plan is available for free during + private preview.\"}]},{\"id\":\"learn_and_develop\",\"version\":\"1.0.1\",\"name\":\"Learn + & Develop\",\"description\":\"Learn and develop with SQBM+ (not for operational + use).\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"quotaDimensions\":[{\"id\":\"learn_and_develop_concurrent_jobs\",\"scope\":\"Workspace\"},{\"id\":\"learn_and_develop_job_execution_time\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"

Up + to 1 concurrent jobs.

1 hour of compute per month.

\"},{\"id\":\"price\",\"value\":\"This + value loaded from partner center.\"}]},{\"id\":\"performance_at_scale\",\"version\":\"1.0.1\",\"name\":\"Performance + at scale\",\"description\":\"Deploy world-class SQBM+ solutions.\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"quotaDimensions\":[{\"id\":\"performance_at_scale_concurrent_jobs\",\"scope\":\"Workspace\"},{\"id\":\"performance_at_scale_job_execution_time\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"

Up + to 3 concurrent jobs.

2,500 hours of compute per month.

\"},{\"id\":\"price\",\"value\":\"This + value loaded from partner center.\"}]}],\"quotaDimensions\":[{\"id\":\"learn_and_develop_concurrent_jobs\",\"scope\":\"Workspace\",\"quota\":1,\"name\":\"Concurrent + jobs\",\"description\":\"The number of jobs that you can submit within a single + workspace at the same time.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"},{\"id\":\"learn_and_develop_job_execution_time\",\"scope\":\"Subscription\",\"quota\":1,\"period\":\"Monthly\",\"name\":\"Computing + hours per month\",\"description\":\"Computing hours within a subscription + per month.\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"performance_at_scale_concurrent_jobs\",\"scope\":\"Workspace\",\"quota\":3,\"name\":\"Concurrent + jobs\",\"description\":\"The number of jobs that you can submit within a single + workspace at the same time.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"},{\"id\":\"performance_at_scale_job_execution_time\",\"scope\":\"Subscription\",\"quota\":2500,\"period\":\"Monthly\",\"name\":\"Computing + hours per month\",\"description\":\"Computing hours within a subscription + per month.\",\"unit\":\"hour\",\"unitPlural\":\"hours\"}],\"pricingDimensions\":[{\"id\":\"targets\",\"name\":\"Targets + available\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Price + per month\"}]}}]}" + headers: + cache-control: + - no-cache + content-length: + - '41041' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:42 GMT + expires: + - '-1' + mise-correlation-id: + - 6fb27320-9d0e-4bdc-b7de-6b933b77ed92 + pragma: + - no-cache + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + set-cookie: + - ARRAffinity=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ARRAffinitySameSite=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;SameSite=None;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + path=/; secure + - ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + samesite=none; path=/; secure + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-azure-ref: + - 0jeXKYwAAAABWUw/wC54bSakoyGo90fgfTU5aMjIxMDYwNjE0MDI5AGU0ODIyNTNiLTllMDUtNDA1ZS1hODNmLTU4NmVlMWQ1NTNlNA== + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current","name":"pay-as-you-go-cred","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"ionqinc1582730893633","product":"ionq-aq","plan":"pay-as-you-go-cred","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_IONQINC1582730893633%253a24IONQ%253a2DAQ%253a24PAY%253a2DAS%253a2DYOU%253a2DGO%253a2DCRED%253a247ODGLEAK7RQISNHUEU4KJYVC6QLVZF5IANNQFGBHOKJMXWIW3OPRUADLB63ROSGS5FVYSHLINGX5BK7GF7Y2ZO24HKBHSPKMXBHFBAQ.txt","privacyPolicyLink":"https://ionq.com/privacy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:45.6167933Z","signature":"RVA52GI5HVUXDUK4L33MCQRODA7OXRLVZLREDVXSWOTOP2RUWMQKSX52PVAHNZC5VHW2GFCXHDN5YOYJBXQUB63S74JQOHTHOQK3WRA","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:45.8355212+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:45.8355212+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1448' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:45 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current","name":"credits1","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"quantinuumllc1640113159771","product":"quantinuum-aq","plan":"credits1","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_QUANTINUUMLLC1640113159771%253a24QUANTINUUM%253a2DAQ%253a24CREDITS1%253a24U3AGC77IHGZ5FLJYZ6QWF357B7LQHG6PW5CSVK7VKS2YGVWO4OBIOCCOCSXJEEP6BMMDOPFM4ETZZYATWBPM2EFN4YT4KWM6QDFMTOY.txt","privacyPolicyLink":"https://www.quantinuum.com/privacy-statement","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:48.1858181Z","signature":"NBVQZQ7KPMHVGW6AGK2X4C2Y2DZSYN36RUPQYOS5E3Z6A7TI4B2O4HY2NBBVN65QEDMEBJ3GNY33IJALILC26JAG6DPQ6LFKAVRNBIQ","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:48.2483186+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:48.2483186+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1440' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:47 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current","name":"azure-quantum-credits","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"rigetticoinc1644276861431","product":"rigetti-aq","plan":"azure-quantum-credits","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_RIGETTICOINC1644276861431%253a24RIGETTI%253a2DAQ%253a24AZURE%253a2DQUANTUM%253a2DCREDITS%253a24H35R3FYQURHQDNSLAZ4YCHIHABQ4NR4UI66LMJ3K53EHCQWZJMC3BLGZODKSAMOQ4ZI5CVO37XQXKFBQ3YWK444S7B3XGBK67JHVZNI.txt","privacyPolicyLink":"https://www.rigetti.com/privacy-policy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:50.5480142Z","signature":"3ZNIUHASJWR27VXEU73UN4ONBFIFTGLIZGD6LGUPP3DQSFZQUYTIUZLUBM6BA275NWAGPOYTMBFYT2HMHCODZKUCROACCHX3WYW5B6Y","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:50.6261369+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:50.6261369+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1486' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:50 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current","name":"pay-as-you-go-cred","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"ionqinc1582730893633","product":"ionq-aq","plan":"pay-as-you-go-cred","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_IONQINC1582730893633%253a24IONQ%253a2DAQ%253a24PAY%253a2DAS%253a2DYOU%253a2DGO%253a2DCRED%253a247ODGLEAK7RQISNHUEU4KJYVC6QLVZF5IANNQFGBHOKJMXWIW3OPRUADLB63ROSGS5FVYSHLINGX5BK7GF7Y2ZO24HKBHSPKMXBHFBAQ.txt","privacyPolicyLink":"https://ionq.com/privacy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:53.3988364Z","signature":"WU7A7ZKOMRIX7E37VN263MXKYCIC4J3DG4JG5X2SL67WYHFSEGGCXN3XJUQGULILXH5RSMDQP6Q2VDS7TYCGLY34RBWCE4R623UE2YI","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:53.6332309+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:53.6332309+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1448' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:53 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current","name":"credits1","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"quantinuumllc1640113159771","product":"quantinuum-aq","plan":"credits1","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_QUANTINUUMLLC1640113159771%253a24QUANTINUUM%253a2DAQ%253a24CREDITS1%253a24U3AGC77IHGZ5FLJYZ6QWF357B7LQHG6PW5CSVK7VKS2YGVWO4OBIOCCOCSXJEEP6BMMDOPFM4ETZZYATWBPM2EFN4YT4KWM6QDFMTOY.txt","privacyPolicyLink":"https://www.quantinuum.com/privacy-statement","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:56.243642Z","signature":"QBU5N5FDU72W4O7S6LJ6ZFB4Q7VIWXANZMH7H35ILYEBGOYC5BH7F2FFQEUSMJQYDMGIQW5FWFXPKQGOFVXNQRUQIGVH4SKDI3J7XCQ","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:56.338663+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:56.338663+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1437' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:55 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current","name":"azure-quantum-credits","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"rigetticoinc1644276861431","product":"rigetti-aq","plan":"azure-quantum-credits","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_RIGETTICOINC1644276861431%253a24RIGETTI%253a2DAQ%253a24AZURE%253a2DQUANTUM%253a2DCREDITS%253a24H35R3FYQURHQDNSLAZ4YCHIHABQ4NR4UI66LMJ3K53EHCQWZJMC3BLGZODKSAMOQ4ZI5CVO37XQXKFBQ3YWK444S7B3XGBK67JHVZNI.txt","privacyPolicyLink":"https://www.rigetti.com/privacy-policy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-20T19:03:58.875214Z","signature":"DX7EDC7PLJBK3N4ZGHHP4RC4VVI56IMEYH6SJQ3LFIOCXKXFW5ZUMKYH2EVLIEYWY2L72JLFKOO6TQ2GAGS4UDZ7EPMW5SKEFGOTOHA","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-20T19:03:58.9689391+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-20T19:03:58.9689391+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1485' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:58 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts?api-version=2022-09-01 + response: + body: + string: '{"value":[{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","name":"vwjonesstorage2","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2021-09-21T22:04:47.1374328Z","key2":"2021-09-21T22:04:47.1374328Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-09-21T22:04:47.0124593Z","primaryEndpoints":{"blob":"https://vwjonesstorage2.blob.core.windows.net/","queue":"https://vwjonesstorage2.queue.core.windows.net/","table":"https://vwjonesstorage2.table.core.windows.net/","file":"https://vwjonesstorage2.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage3","name":"vwjonesstorage3","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-08-11T18:41:05.2371860Z","key2":"2022-08-11T18:41:05.2371860Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-11T18:41:05.2371860Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-11T18:41:05.2371860Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-08-11T18:41:05.0652888Z","primaryEndpoints":{"blob":"https://vwjonesstorage3.blob.core.windows.net/","queue":"https://vwjonesstorage3.queue.core.windows.net/","table":"https://vwjonesstorage3.table.core.windows.net/","file":"https://vwjonesstorage3.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage33310","name":"vwjonesstorage33310","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-12-13T02:10:06.0148695Z","key2":"2022-12-13T02:10:06.0148695Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-12-13T02:10:06.0148695Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-12-13T02:10:06.0148695Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-12-13T02:10:05.8273595Z","primaryEndpoints":{"blob":"https://vwjonesstorage33310.blob.core.windows.net/","queue":"https://vwjonesstorage33310.queue.core.windows.net/","table":"https://vwjonesstorage33310.table.core.windows.net/","file":"https://vwjonesstorage33310.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage4","name":"vwjonesstorage4","type":"Microsoft.Storage/storageAccounts","location":"westus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-08-24T18:30:25.3831084Z","key2":"2022-08-24T18:30:25.3831084Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-24T18:30:25.3987025Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-24T18:30:25.3987025Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-08-24T18:30:25.2580954Z","primaryEndpoints":{"blob":"https://vwjonesstorage4.blob.core.windows.net/","queue":"https://vwjonesstorage4.queue.core.windows.net/","table":"https://vwjonesstorage4.table.core.windows.net/","file":"https://vwjonesstorage4.file.core.windows.net/"},"primaryLocation":"westus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"StorageV2","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage5","name":"vwjonesstorage5","type":"Microsoft.Storage/storageAccounts","location":"westus2","tags":{},"properties":{"dnsEndpointType":"Standard","defaultToOAuthAuthentication":false,"publicNetworkAccess":"Enabled","keyCreationTime":{"key1":"2022-08-25T21:57:16.1412273Z","key2":"2022-08-25T21:57:16.1412273Z"},"allowCrossTenantReplication":true,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_2","allowBlobPublicAccess":true,"allowSharedKeyAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"requireInfrastructureEncryption":false,"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-25T21:57:16.5630689Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-25T21:57:16.5630689Z"}},"keySource":"Microsoft.Storage"},"accessTier":"Hot","provisioningState":"Succeeded","creationTime":"2022-08-25T21:57:16.0474739Z","primaryEndpoints":{"dfs":"https://vwjonesstorage5.dfs.core.windows.net/","web":"https://vwjonesstorage5.z5.web.core.windows.net/","blob":"https://vwjonesstorage5.blob.core.windows.net/","queue":"https://vwjonesstorage5.queue.core.windows.net/","table":"https://vwjonesstorage5.table.core.windows.net/","file":"https://vwjonesstorage5.file.core.windows.net/"},"primaryLocation":"westus2","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage7","name":"vwjonesstorage7","type":"Microsoft.Storage/storageAccounts","location":"eastus2euap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-09-29T22:32:06.2588030Z","key2":"2022-09-29T22:32:06.2588030Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:32:06.7900691Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:32:06.7900691Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-09-29T22:32:06.1806703Z","primaryEndpoints":{"blob":"https://vwjonesstorage7.blob.core.windows.net/","queue":"https://vwjonesstorage7.queue.core.windows.net/","table":"https://vwjonesstorage7.table.core.windows.net/","file":"https://vwjonesstorage7.file.core.windows.net/"},"primaryLocation":"eastus2euap","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage6","name":"vwjonesstorage6","type":"Microsoft.Storage/storageAccounts","location":"centraluseuap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-09-29T22:13:05.8017810Z","key2":"2022-09-29T22:13:05.8017810Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:13:06.3017835Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:13:06.3017835Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-09-29T22:13:05.7392784Z","primaryEndpoints":{"blob":"https://vwjonesstorage6.blob.core.windows.net/","queue":"https://vwjonesstorage6.queue.core.windows.net/","table":"https://vwjonesstorage6.table.core.windows.net/","file":"https://vwjonesstorage6.file.core.windows.net/"},"primaryLocation":"centraluseuap","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstoragecanary","name":"vwjonesstoragecanary","type":"Microsoft.Storage/storageAccounts","location":"centraluseuap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-10-27T21:45:38.3454788Z","key2":"2022-10-27T21:45:38.3454788Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-10-27T21:45:38.3454788Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-10-27T21:45:38.3454788Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-10-27T21:45:38.2829751Z","primaryEndpoints":{"blob":"https://vwjonesstoragecanary.blob.core.windows.net/","queue":"https://vwjonesstoragecanary.queue.core.windows.net/","table":"https://vwjonesstoragecanary.table.core.windows.net/","file":"https://vwjonesstoragecanary.file.core.windows.net/"},"primaryLocation":"centraluseuap","statusOfPrimary":"available"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '10770' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:03:58 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-original-request-ids: + - 7ed43851-3112-4f37-8f7e-5bd4e0439d58 + - f217e0f7-c6fa-4b7c-b706-b43eb59ec1aa + - 620fae5d-b7d2-4f4c-a7a0-f2c7e18da86d + - 6b34fc14-bfab-4910-91a6-b3e3f83eb2ff + - f3f96f03-0f4c-4200-8fc7-bdd9e0c6ed94 + status: + code: 200 + message: OK +- request: + body: '{"properties": {"template": {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "parameters": {"quantumWorkspaceName": {"type": + "string", "metadata": {"description": "Quantum Workspace Name"}}, "location": + {"type": "string", "metadata": {"description": "Workspace Location"}}, "tags": + {"type": "object", "defaultValue": {}, "metadata": {"description": "Tags for + this workspace"}}, "providers": {"type": "array", "metadata": {"description": + "A list of Providers for this workspace"}}, "storageAccountName": {"type": "string", + "metadata": {"description": "Storage account short name"}}, "storageAccountId": + {"type": "string", "metadata": {"description": "Storage account ID (path)"}}, + "storageAccountLocation": {"type": "string", "metadata": {"description": "Storage + account location"}}, "storageAccountSku": {"type": "string", "metadata": {"description": + "Storage account SKU"}}, "storageAccountKind": {"type": "string", "metadata": + {"description": "Kind of storage account"}}, "storageAccountDeploymentName": + {"type": "string", "metadata": {"description": "Deployment name for role assignment + operation"}}}, "functions": [], "variables": {}, "resources": [{"type": "Microsoft.Quantum/workspaces", + "apiVersion": "2019-11-04-preview", "name": "[parameters(''quantumWorkspaceName'')]", + "location": "[parameters(''location'')]", "tags": "[parameters(''tags'')]", + "identity": {"type": "SystemAssigned"}, "properties": {"providers": "[parameters(''providers'')]", + "storageAccount": "[parameters(''storageAccountId'')]"}}, {"apiVersion": "2019-10-01", + "name": "[parameters(''storageAccountDeploymentName'')]", "type": "Microsoft.Resources/deployments", + "dependsOn": ["[resourceId(''Microsoft.Quantum/Workspaces'', parameters(''quantumWorkspaceName''))]"], + "properties": {"mode": "Incremental", "template": {"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "resources": [{"apiVersion": "2019-06-01", "name": + "[parameters(''storageAccountName'')]", "location": "[parameters(''storageAccountLocation'')]", + "type": "Microsoft.Storage/storageAccounts", "sku": {"name": "[parameters(''storageAccountSku'')]"}, + "kind": "[parameters(''storageAccountKind'')]", "resources": [{"name": "default", + "type": "fileServices", "apiVersion": "2019-06-01", "dependsOn": ["[parameters(''storageAccountId'')]"], + "properties": {"cors": {"corsRules": [{"allowedOrigins": ["*"], "allowedHeaders": + ["*"], "allowedMethods": ["GET", "HEAD", "OPTIONS", "POST", "PUT"], "exposedHeaders": + ["*"], "maxAgeInSeconds": 180}]}}}]}, {"apiVersion": "2020-04-01-preview", "name": + "[concat(parameters(''storageAccountName''), ''/Microsoft.Authorization/'', + guid(reference(concat(''Microsoft.Quantum/Workspaces/'', parameters(''quantumWorkspaceName'')), + ''2019-11-04-preview'', ''Full'').identity.principalId))]", "type": "Microsoft.Storage/storageAccounts/providers/roleAssignments", + "location": "[parameters(''storageAccountLocation'')]", "properties": {"roleDefinitionId": + "[resourceId(''Microsoft.Authorization/roleDefinitions'', ''b24988ac-6180-42a0-ab88-20f7382dd24c'')]", + "principalId": "[reference(concat(''Microsoft.Quantum/Workspaces/'', parameters(''quantumWorkspaceName'')), + ''2019-11-04-preview'', ''Full'').identity.principalId]", "principalType": "ServicePrincipal"}, + "dependsOn": ["[parameters(''storageAccountId'')]"]}]}}}], "outputs": {}}, "parameters": + {"quantumWorkspaceName": {"value": "e2e-test-w6358292"}, "location": {"value": + "eastus"}, "tags": {"value": {}}, "providers": {"value": [{"providerId": "microsoft-qc", + "providerSku": "learn-and-develop"}, {"providerId": "ionq", "providerSku": "pay-as-you-go-cred"}, + {"providerId": "Microsoft", "providerSku": "DZH3178M639F"}, {"providerId": "quantinuum", + "providerSku": "credits1"}, {"providerId": "rigetti", "providerSku": "azure-quantum-credits"}]}, + "storageAccountName": {"value": "vwjonesstorage2"}, "storageAccountId": {"value": + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"}, + "storageAccountLocation": {"value": "eastus"}, "storageAccountSku": {"value": + "Standard_LRS"}, "storageAccountKind": {"value": "Storage"}, "storageAccountDeploymentName": + {"value": "Microsoft.StorageAccount-20-Jan-2023-19-03-59"}}, "mode": "Incremental"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '4350' + Content-Type: + - application/json + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2021-04-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w6358292","name":"Microsoft.AzureQuantum-e2e-test-w6358292","type":"Microsoft.Resources/deployments","properties":{"templateHash":"6354453805046911057","parameters":{"quantumWorkspaceName":{"type":"String","value":"e2e-test-w6358292"},"location":{"type":"String","value":"eastus"},"tags":{"type":"Object","value":{}},"providers":{"type":"Array","value":[{"providerId":"microsoft-qc","providerSku":"learn-and-develop"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred"},{"providerId":"Microsoft","providerSku":"DZH3178M639F"},{"providerId":"quantinuum","providerSku":"credits1"},{"providerId":"rigetti","providerSku":"azure-quantum-credits"}]},"storageAccountName":{"type":"String","value":"vwjonesstorage2"},"storageAccountId":{"type":"String","value":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},"storageAccountLocation":{"type":"String","value":"eastus"},"storageAccountSku":{"type":"String","value":"Standard_LRS"},"storageAccountKind":{"type":"String","value":"Storage"},"storageAccountDeploymentName":{"type":"String","value":"Microsoft.StorageAccount-20-Jan-2023-19-03-59"}},"mode":"Incremental","provisioningState":"Accepted","timestamp":"2023-01-20T19:04:02.5108628Z","duration":"PT0.0005313S","correlationId":"9ac06a99-7f29-4b84-9e5f-7f5d5afa05ef","providers":[{"namespace":"Microsoft.Quantum","resourceTypes":[{"resourceType":"workspaces","locations":["eastus"]}]},{"namespace":"Microsoft.Resources","resourceTypes":[{"resourceType":"deployments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/Workspaces/e2e-test-w6358292","resourceType":"Microsoft.Quantum/Workspaces","resourceName":"e2e-test-w6358292"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292","resourceType":"Microsoft.Quantum/workspaces","resourceName":"e2e-test-w6358292","apiVersion":"2019-11-04-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.StorageAccount-20-Jan-2023-19-03-59","resourceType":"Microsoft.Resources/deployments","resourceName":"Microsoft.StorageAccount-20-Jan-2023-19-03-59"}]}}' + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w6358292/operationStatuses/08585273654438437744?api-version=2021-04-01 + cache-control: + - no-cache + content-length: + - '2554' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:04:01 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Accepted"}' + headers: + cache-control: + - no-cache + content-length: + - '21' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:04:01 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:04:32 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:05:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + connection: + - close + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:05:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:06:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:06:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:07:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:07:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:08:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:08:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585273654438437744?api-version=2021-04-01 + response: + body: + string: '{"status":"Succeeded"}' + headers: + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2021-04-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w6358292","name":"Microsoft.AzureQuantum-e2e-test-w6358292","type":"Microsoft.Resources/deployments","properties":{"templateHash":"6354453805046911057","parameters":{"quantumWorkspaceName":{"type":"String","value":"e2e-test-w6358292"},"location":{"type":"String","value":"eastus"},"tags":{"type":"Object","value":{}},"providers":{"type":"Array","value":[{"providerId":"microsoft-qc","providerSku":"learn-and-develop"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred"},{"providerId":"Microsoft","providerSku":"DZH3178M639F"},{"providerId":"quantinuum","providerSku":"credits1"},{"providerId":"rigetti","providerSku":"azure-quantum-credits"}]},"storageAccountName":{"type":"String","value":"vwjonesstorage2"},"storageAccountId":{"type":"String","value":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},"storageAccountLocation":{"type":"String","value":"eastus"},"storageAccountSku":{"type":"String","value":"Standard_LRS"},"storageAccountKind":{"type":"String","value":"Storage"},"storageAccountDeploymentName":{"type":"String","value":"Microsoft.StorageAccount-20-Jan-2023-19-03-59"}},"mode":"Incremental","provisioningState":"Succeeded","timestamp":"2023-01-20T19:09:01.2033975Z","duration":"PT4M58.693066S","correlationId":"9ac06a99-7f29-4b84-9e5f-7f5d5afa05ef","providers":[{"namespace":"Microsoft.Quantum","resourceTypes":[{"resourceType":"workspaces","locations":["eastus"]}]},{"namespace":"Microsoft.Resources","resourceTypes":[{"resourceType":"deployments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/Workspaces/e2e-test-w6358292","resourceType":"Microsoft.Quantum/Workspaces","resourceName":"e2e-test-w6358292"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292","resourceType":"Microsoft.Quantum/workspaces","resourceName":"e2e-test-w6358292","apiVersion":"2019-11-04-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.StorageAccount-20-Jan-2023-19-03-59","resourceType":"Microsoft.Resources/deployments","resourceName":"Microsoft.StorageAccount-20-Jan-2023-19-03-59"}],"outputs":{},"outputResources":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/fileServices/default"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/providers/Microsoft.Authorization/roleAssignments/503a3621-2e9c-50f7-a6c4-fb765449f56e"}]}}' + headers: + cache-control: + - no-cache + content-length: + - '3291' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292/providerStatus + response: + body: + string: '{"value":[{"id":"microsoft-qc","currentAvailability":"Available","targets":[{"id":"microsoft.estimator","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"ionq","currentAvailability":"Available","targets":[{"id":"ionq.qpu","currentAvailability":"Available","averageQueueTime":17493,"statusPage":"https://status.ionq.co"},{"id":"ionq.qpu.aria-1","currentAvailability":"Available","averageQueueTime":908201,"statusPage":"https://status.ionq.co"},{"id":"ionq.simulator","currentAvailability":"Available","averageQueueTime":3,"statusPage":"https://status.ionq.co"}]},{"id":"Microsoft","currentAvailability":"Available","targets":[{"id":"microsoft.paralleltempering-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.paralleltempering.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.qmc.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"quantinuum","currentAvailability":"Degraded","targets":[{"id":"quantinuum.hqs-lt-s1","currentAvailability":"Available","averageQueueTime":34708,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-apival","currentAvailability":"Available","averageQueueTime":24,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-apival","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-sim","currentAvailability":"Available","averageQueueTime":14638,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-sim","currentAvailability":"Available","averageQueueTime":21,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-1","currentAvailability":"Available","averageQueueTime":34708,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1sc","currentAvailability":"Available","averageQueueTime":24,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2sc","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1e","currentAvailability":"Available","averageQueueTime":14638,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2e","currentAvailability":"Available","averageQueueTime":21,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null}]},{"id":"rigetti","currentAvailability":"Degraded","targets":[{"id":"rigetti.sim.qvm","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-11","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null},{"id":"rigetti.qpu.aspen-m-2","currentAvailability":"Degraded","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-m-3","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"}]}],"nextLink":null}' + headers: + connection: + - keep-alive + content-length: + - '4552' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:07 GMT + mise-correlation-id: + - cd8b321d-2bde-4c66-a409-41554a52fd48 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292/providerStatus + response: + body: + string: '{"value":[{"id":"microsoft-qc","currentAvailability":"Available","targets":[{"id":"microsoft.estimator","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"ionq","currentAvailability":"Available","targets":[{"id":"ionq.qpu","currentAvailability":"Available","averageQueueTime":17493,"statusPage":"https://status.ionq.co"},{"id":"ionq.qpu.aria-1","currentAvailability":"Available","averageQueueTime":908201,"statusPage":"https://status.ionq.co"},{"id":"ionq.simulator","currentAvailability":"Available","averageQueueTime":3,"statusPage":"https://status.ionq.co"}]},{"id":"Microsoft","currentAvailability":"Available","targets":[{"id":"microsoft.paralleltempering-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.paralleltempering.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.qmc.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"quantinuum","currentAvailability":"Degraded","targets":[{"id":"quantinuum.hqs-lt-s1","currentAvailability":"Available","averageQueueTime":34708,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-apival","currentAvailability":"Available","averageQueueTime":24,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-apival","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-sim","currentAvailability":"Available","averageQueueTime":14638,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-sim","currentAvailability":"Available","averageQueueTime":21,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-1","currentAvailability":"Available","averageQueueTime":34708,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1sc","currentAvailability":"Available","averageQueueTime":24,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2sc","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1e","currentAvailability":"Available","averageQueueTime":14638,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2e","currentAvailability":"Available","averageQueueTime":21,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null}]},{"id":"rigetti","currentAvailability":"Degraded","targets":[{"id":"rigetti.sim.qvm","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-11","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null},{"id":"rigetti.qpu.aspen-m-2","currentAvailability":"Degraded","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-m-3","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"}]}],"nextLink":null}' + headers: + connection: + - keep-alive + content-length: + - '4552' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:07 GMT + mise-correlation-id: + - 1f695a40-c0c9-42d6-9d17-5c129a611007 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -g -w + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292?api-version=2022-01-10-preview + response: + body: + string: 'null' + headers: + azure-asyncoperation: + - https://management.azure.com/providers/Microsoft.Quantum/locations/EASTUS/operationStatuses/93c3e403-6fd8-4ae6-919a-27c5f4e1455f*35023C7D7A6F36DD69B9780F798D55E04B80101294997BCEB8BE5D9EE5FBE7B0?api-version=2022-01-10-preview + cache-control: + - no-cache + content-length: + - '4' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:07 GMT + etag: + - '"4500f8ed-0000-0100-0000-63cae6d40000"' + expires: + - '-1' + location: + - https://management.azure.com/providers/Microsoft.Quantum/locations/EASTUS/operationStatuses/93c3e403-6fd8-4ae6-919a-27c5f4e1455f*35023C7D7A6F36DD69B9780F798D55E04B80101294997BCEB8BE5D9EE5FBE7B0?api-version=2022-01-10-preview + mise-correlation-id: + - 4e626981-d530-465b-a92a-f6a17a9227bd + pragma: + - no-cache + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + set-cookie: + - ARRAffinity=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ARRAffinitySameSite=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;SameSite=None;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + path=/; secure + - ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + samesite=none; path=/; secure + strict-transport-security: + - max-age=31536000; includeSubDomains + x-azure-ref: + - 01ObKYwAAAABOjAMZwSlFTIu9erCZzXJjTU5aMjIxMDYwNjEzMDUzAGU0ODIyNTNiLTllMDUtNDA1ZS1hODNmLTU4NmVlMWQ1NTNlNA== + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + x-ms-ratelimit-remaining-subscription-deletes: + - '14999' + x-powered-by: + - ASP.NET + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace delete + Connection: + - keep-alive + Cookie: + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548 + ParameterSetName: + - -g -w + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292?api-version=2022-01-10-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w6358292","name":"e2e-test-w6358292","type":"microsoft.quantum/workspaces","location":"eastus","tags":{},"systemData":{"createdBy":"v-wjones@microsoft.com","createdByType":"User","createdAt":"2023-01-20T19:04:04.9195724Z","lastModifiedBy":"v-wjones@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-01-20T19:04:04.9195724Z"},"identity":{"principalId":"e2c36b92-54c3-4ef3-ae2d-334e90acbe66","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"providers":[{"providerId":"microsoft-qc","providerSku":"learn-and-develop","applicationName":"e2e-test-w6358292-microsoft-qc","provisioningState":"Succeeded"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred","applicationName":"e2e-test-w6358292-ionq","provisioningState":"Succeeded","resourceUsageId":"fe2b3f5d-7627-4135-82fd-7c853bd1c800"},{"providerId":"Microsoft","providerSku":"DZH3178M639F","applicationName":"e2e-test-w6358292-Microsoft","provisioningState":"Succeeded"},{"providerId":"quantinuum","providerSku":"credits1","applicationName":"e2e-test-w6358292-quantinuum","provisioningState":"Succeeded","resourceUsageId":"465e53bd-002d-45d1-a39c-86e83f30680d"},{"providerId":"rigetti","providerSku":"azure-quantum-credits","applicationName":"e2e-test-w6358292-rigetti","provisioningState":"Succeeded","resourceUsageId":"59090a45-56a1-49b9-bb85-840f5e7840be"}],"provisioningState":"Deleting","usable":"Yes","storageAccount":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","endpointUri":"https://e2e-test-w6358292.eastus.quantum.azure.com"}}' + headers: + cache-control: + - no-cache + content-length: + - '1778' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 20 Jan 2023 19:09:08 GMT + etag: + - '"4500f8ed-0000-0100-0000-63cae6d40000"' + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + status: + code: 200 + message: OK +version: 1 diff --git a/src/quantum/azext_quantum/tests/latest/recordings/test_submit.yaml b/src/quantum/azext_quantum/tests/latest/recordings/test_submit.yaml new file mode 100644 index 00000000000..051abcda551 --- /dev/null +++ b/src/quantum/azext_quantum/tests/latest/recordings/test_submit.yaml @@ -0,0 +1,3326 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Quantum/locations/eastus/offerings?api-version=2022-01-10-preview + response: + body: + string: "{\"value\":[{\"id\":\"1qbit\",\"name\":\"1Qloud Optimization Platform\",\"properties\":{\"description\":\"1QBit + 1Qloud Optimization Platform with Quantum Inspired Solutions\",\"providerType\":\"qio\",\"company\":\"1QBit\",\"managedApplication\":{\"publisherId\":\"1qbinformationtechnologies1580939206424\",\"offerId\":\"1qbit-1qloud-optimization-aq\"},\"targets\":[{\"id\":\"1qbit.tabu\",\"name\":\"1QBit + Quadratic Tabu Solver\",\"description\":\"An iterative heuristic algorithm + that uses local search techniques to solve a problem\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"1qbit.pathrelinking\",\"name\":\"1QBit + Quadratic Path-Relinking Solver\",\"description\":\"The path-relinking algorithm + is a heuristic algorithm that uses the tabu search as a subroutine to solve + a QUBO problem\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"1qbit.pticm\",\"name\":\"1QBit + Quadratic Parallel Tempering Isoenergetic Cluster Moves Solver\",\"description\":\"The + parallel tempering with isoenergetic cluster moves (PTICM) solver is a Monte + Carlo approach to solving QUBO problems\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"1qbit-internal-free-plan\",\"version\":\"1.0.3\",\"name\":\"1QBit + No Charge Plan\",\"description\":\"1QBit plan with no charge for specific + customer arrangements\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"Free + for select customers\"}]},{\"id\":\"1qbit-fixed-monthly-202012\",\"version\":\"1.0.3\",\"name\":\"Fixed + Monthly Plan\",\"description\":\"This plan provides access to all 1QBit quantum-inspired + optimization solvers with a flat monthly fee\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$7500 + USD per month\"}]},{\"id\":\"1qbit-pay-as-you-go-20210428\",\"version\":\"1.0.3\",\"name\":\"Pay + As You Go by CPU Usage\",\"description\":\"This plan provides access to all + 1QBit quantum-inspired optimization solvers with a pay as you go pricing\",\"autoAdd\":false,\"targets\":[\"1qbit.tabu\",\"1qbit.pathrelinking\",\"1qbit.pticm\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Tabu + Search Solver
Path-Relinking Solver
PTICM Solver\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$0.075 + per minute; rounded up to nearest second, with a minimum 1-second charge per + solve request\"}]}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"ionq\",\"name\":\"IonQ\",\"properties\":{\"description\":\"IonQ\u2019s + trapped ion quantum computers perform calculations by manipulating charged + atoms of Ytterbium held in a vacuum with lasers.\",\"providerType\":\"qe\",\"company\":\"IonQ\",\"managedApplication\":{\"publisherId\":\"ionqinc1582730893633\",\"offerId\":\"ionq-aq\"},\"targets\":[{\"id\":\"ionq.simulator\",\"name\":\"Trapped + Ion Quantum Computer Simulator\",\"description\":\"GPU-accelerated idealized + simulator supporting up to 29 qubits, using the same gates IonQ provides on + its quantum computers. No errors are modeled at present.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu\",\"name\":\"Trapped + Ion Quantum Computer\",\"description\":\"IonQ's quantum computer is dynamically + reconfigurable in software to use up to 11 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu.aria-1\",\"name\":\"Aria + 1\",\"description\":\"IonQ's Aria 1 quantum computer is dynamically reconfigurable + in software to use up to 23 qubits. All qubits are fully connected, meaning + you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.circuit.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.simulator-preview\",\"name\":\"Trapped + Ion Quantum Computer Simulator Preview\",\"description\":\"GPU-accelerated + idealized simulator supporting up to 29 qubits, using the same gates IonQ + provides on its quantum computers. No errors are modeled at present.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu-preview\",\"name\":\"Harmony + Preview\",\"description\":\"IonQ's Harmony quantum computer is dynamically + reconfigurable in software to use up to 11 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"ionq.qpu.aria-1-preview\",\"name\":\"Aria + 1 Preview\",\"description\":\"IonQ's Aria 1 quantum computer is dynamically + reconfigurable in software to use up to 23 qubits. All qubits are fully connected, + meaning you can run a two-qubit gate between any pair.\",\"acceptedDataFormats\":[\"ionq.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"pay-as-you-go-cred\",\"version\":\"0.0.5\",\"name\":\"Azure + Quantum Credits\",\"description\":\"The Azure Quantum Credits program provides + sponsored access to IonQ hardware through Azure. You will not be charged for + usage created under the credits program.\",\"autoAdd\":true,\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"quotaDimensions\":[{\"id\":\"qgs\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Aria Trapped + Ion QC (23 qubits)
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"$500 worth + of IonQ compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.\"}]},{\"id\":\"pay-as-you-go\",\"version\":\"0.0.5\",\"name\":\"Pay + As You Go\",\"description\":\"A la carte access based on resource requirements + and usage.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"No limit\"},{\"id\":\"price\",\"value\":\"$ + 3,000.00 USD / hour (est)
See documentation for details\"}]},{\"id\":\"committed-subscription-2\",\"version\":\"0.0.5\",\"name\":\"Subscription\",\"description\":\"Committed + access to all of IonQ's quantum computers\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:partnerships@ionq.co\",\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Aria Trapped + Ion QC (23 qubits)
Harmony + Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"$ + 25,000.00 USD / month
See documentation for details\"}]},{\"id\":\"private-preview-free\",\"version\":\"0.0.5\",\"name\":\"QIR + Private Preview Free\",\"description\":\"Submit QIR jobs to IonQ quantum platform.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + QIR job execution\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"N/A\"}]},{\"id\":\"preview-internal\",\"version\":\"0.0.5\",\"name\":\"Internal + Preview\",\"description\":\"Internal preview with zero cost.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\",\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Internal Preview\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"N/A\"}]},{\"id\":\"aq-internal-testing\",\"version\":\"0.0.1\",\"name\":\"Microsoft + Internal Testing\",\"description\":\"You're testing, so it's free! As in beer.\",\"autoAdd\":false,\"targets\":[\"ionq.qpu\",\"ionq.qpu.aria-1\",\"ionq.simulator\",\"ionq.qpu-preview\",\"ionq.qpu.aria-1-preview\",\"ionq.simulator-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"IonQ + Simulator
Harmony Trapped Ion QC (11 qubits)\"},{\"id\":\"quota\",\"value\":\"N/A\"},{\"id\":\"price\",\"value\":\"Free\"}]}],\"quotaDimensions\":[{\"id\":\"qgs\",\"scope\":\"Subscription\",\"quota\":16666667,\"period\":\"Infinite\",\"name\":\"QPU + Credit\",\"description\":\"Credited resource usage against your account. See + IonQ documentation for more information: https://aka.ms/AQ/IonQ/ProviderDocumentation.\",\"unit\":\"qubit-gate-shot\",\"unitPlural\":\"qubit-gate-shots\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Limits\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"Microsoft\",\"name\":\"Microsoft + QIO\",\"properties\":{\"description\":\"Ground-breaking optimization algorithms + inspired by decades of quantum research.\",\"providerType\":\"qio\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.tabu.cpu\",\"name\":\"microsoft.tabu.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.qmc.cpu\",\"name\":\"microsoft.qmc.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.tabu-parameterfree.cpu\",\"name\":\"microsoft.tabu-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.simulatedannealing.cpu\",\"name\":\"microsoft.simulatedannealing.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.simulatedannealing-parameterfree.cpu\",\"name\":\"microsoft.simulatedannealing-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.paralleltempering.cpu\",\"name\":\"microsoft.paralleltempering.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.paralleltempering-parameterfree.cpu\",\"name\":\"microsoft.paralleltempering-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.populationannealing.cpu\",\"name\":\"microsoft.populationannealing.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.substochasticmontecarlo.cpu\",\"name\":\"microsoft.substochasticmontecarlo.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"name\":\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]},{\"id\":\"microsoft.populationannealing-parameterfree.cpu\",\"name\":\"microsoft.populationannealing-parameterfree.cpu\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"Basic\",\"version\":\"1.0\",\"name\":\"Private + Preview\",\"description\":\"Free Private Preview access through February 15 + 2020\",\"autoAdd\":false,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\",\"microsoft.populationannealing-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 5 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"CPU based: 5 hours / month\"},{\"id\":\"price\",\"value\":\"$ + 0\"}]},{\"id\":\"DZH3178M639F\",\"version\":\"1.0\",\"name\":\"Learn & Develop\",\"description\":\"Learn + and develop with Optimization solutions.\",\"autoAdd\":true,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":20},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 5 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"CPU based: 20 hours / month\"},{\"id\":\"price\",\"value\":\"Pay + as you go
1 free hour included

See + pricing sheet\"}]},{\"id\":\"DZH318RV7MW4\",\"version\":\"1.0\",\"name\":\"Scale\",\"description\":\"Deploy + world-class Optimization solutions.\",\"autoAdd\":false,\"targets\":[\"microsoft.paralleltempering-parameterfree.cpu\",\"microsoft.paralleltempering.cpu\",\"microsoft.simulatedannealing-parameterfree.cpu\",\"microsoft.simulatedannealing.cpu\",\"microsoft.tabu-parameterfree.cpu\",\"microsoft.tabu.cpu\",\"microsoft.qmc.cpu\",\"microsoft.populationannealing.cpu\",\"microsoft.populationannealing-parameterfree.cpu\",\"microsoft.substochasticmontecarlo.cpu\",\"microsoft.substochasticmontecarlo-parameterfree.cpu\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":1000},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":100}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"Simulated + Annealing
Parallel Tempering
Tabu Search
Substochastic Monte Carlo
Population + Annealing
all solvers above have a parameter-free mode

Quantum + Monte Carlo\"},{\"id\":\"perf\",\"value\":\"CPU based: Up to 100 concurrent + jobs\"},{\"id\":\"quota\",\"value\":\"Up to 50,000 hours / month\"},{\"id\":\"price\",\"value\":\"Pay + as you go
1 free hour included

See + pricing sheet\"}]},{\"id\":\"EarlyAccess\",\"version\":\"1.0\",\"name\":\"Early + Access\",\"description\":\"Help us test new capabilities in our Microsoft + Optimization provider. This SKU is available to a select group of users and + limited to targets that we are currently running an Early Access test for.\",\"autoAdd\":false,\"targets\":[],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":10},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"No + available targets.\"},{\"id\":\"quota\",\"value\":\"CPU based: 10 hours / + month\"},{\"id\":\"price\",\"value\":\"$ 0\"}]}],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":5,\"period\":\"Monthly\",\"name\":\"CPU + Solver Hours [Workspace]\",\"description\":\"The amount of CPU solver time + you may use per month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"CPU + Solver Hours [Subscription]\",\"description\":\"The amount of CPU solver time + you may use per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":5}],\"pricingDimensions\":[{\"id\":\"targets\",\"name\":\"Targets + available\"},{\"id\":\"perf\",\"name\":\"Performance\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Price + per month\"}]}},{\"id\":\"microsoft-qc\",\"name\":\"Microsoft Quantum Computing\",\"properties\":{\"description\":\"Prepare + for fault-tolerant quantum computing with Microsoft specific tools and services, + including the Azure Quantum Resource Estimator.\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.estimator\",\"name\":\"Resource + Estimator\",\"acceptedDataFormats\":[\"microsoft.qir.v1\",\"qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"learn-and-develop\",\"version\":\"1.0\",\"name\":\"Learn + & Develop\",\"description\":\"Free plan including access to hosted notebooks + with pre-configured support for Q#, Qiskit and Cirq, noisy simulator and Azure + Quantum Resource Estimator.\",\"autoAdd\":true,\"targets\":[\"microsoft.estimator\"],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Resource + Estimator

Designed specifically for scaled quantum systems, Azure + Quantum Resource Estimator provides estimates for the number of physical qubits + and runtime required to execute quantum applications on post-NISQ, fault-tolerant + systems.\"},{\"id\":\"quota\",\"value\":\"Up to 10 concurrent jobs.\"},{\"id\":\"price\",\"value\":\"Free + usage.\"}]}],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\",\"quota\":10}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"Microsoft.FleetManagement\",\"name\":\"Microsoft + Fleet Management Solution\",\"properties\":{\"description\":\"(Preview) Leverage + Azure Quantum's advanced optimization algorithms to solve fleet management + problems.\",\"providerType\":\"qio\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.fleetmanagement\",\"name\":\"microsoft.fleetmanagement\",\"acceptedDataFormats\":[\"microsoft.fleetmanagement.v1\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"Basic\",\"version\":\"1.0\",\"name\":\"Private + Preview\",\"description\":\"Private preview fleet management SKU.\",\"autoAdd\":false,\"targets\":[\"microsoft.fleetManagement\"],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\"}]}],\"quotaDimensions\":[{\"id\":\"combined_job_hours\",\"scope\":\"Workspace\",\"quota\":20,\"period\":\"Monthly\",\"name\":\"Job + Hours [Workspace]\",\"description\":\"The amount of job time you may use per + month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"combined_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Job + Hours [Subscription]\",\"description\":\"The amount of job time you may use + per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_cpu_jobs\",\"scope\":\"Workspace\",\"quota\":5}]}},{\"id\":\"Microsoft.Simulator\",\"name\":\"Microsoft + Simulation Tools\",\"properties\":{\"description\":\"Microsoft Simulation + Tools.\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"N/A\",\"offerId\":\"N/A\"},\"targets\":[{\"id\":\"microsoft.simulator.resources-estimator\",\"name\":\"Quantum + Resources Estimator\",\"acceptedDataFormats\":[\"microsoft.qir.v1\",\"qir.v1\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"resources-estimator-preview\",\"version\":\"1.0\",\"name\":\"Resource + Estimation Private Preview\",\"description\":\"Private preview plan for resource + estimation. Provider and target names may change upon public preview.\",\"autoAdd\":false,\"targets\":[\"microsoft.simulator.resources-estimator\"],\"quotaDimensions\":[{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\"}]}],\"quotaDimensions\":[{\"id\":\"simulator_job_hours\",\"scope\":\"Workspace\",\"quota\":20,\"period\":\"Monthly\",\"name\":\"Simulator + Hours [Workspace]\",\"description\":\"The amount of simulator time you may + use per month within this workspace\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"simulator_job_hours\",\"scope\":\"Subscription\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Simulator + Hours [Subscription]\",\"description\":\"The amount of simulator time you + may use per month shared by all workspaces within the subscription\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"concurrent_simulator_jobs\",\"scope\":\"Workspace\",\"quota\":5},{\"id\":\"concurrent_resource_estimator_jobs\",\"scope\":\"Workspace\",\"quota\":10}]}},{\"id\":\"Microsoft.Test\",\"name\":\"Microsoft + Test Provider\",\"properties\":{\"description\":\"Microsoft Test Provider\",\"providerType\":\"qe\",\"company\":\"Microsoft\",\"managedApplication\":{\"publisherId\":\"microsoft_qio\",\"offerId\":\"samplepartner-aq-preview\"},\"targets\":[{\"id\":\"echo-rigetti\",\"name\":\"echo-rigetti\",\"acceptedDataFormats\":[\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-quantinuum\",\"name\":\"echo-quantinuum\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-qci\",\"name\":\"echo-qci\",\"acceptedDataFormats\":[\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"echo-output\",\"name\":\"echo-output\",\"acceptedDataFormats\":[\"microsoft.quantum-log.v1.1\",\"microsoft.quantum-log.v2.1\",\"microsoft.quantum-log.v1\",\"microsoft.quantum-log.v2\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"sample-plan-3\",\"version\":\"1.0.4\",\"name\":\"Standard\",\"description\":\"Standard + services\",\"autoAdd\":false,\"targets\":[\"echo-rigetti\",\"echo-quantinuum\",\"echo-qci\",\"echo-output\"],\"pricingDetails\":[{\"id\":\"price\",\"value\":\"Free\"}]}],\"pricingDimensions\":[{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"qci\",\"name\":\"Quantum + Circuits, Inc.\",\"properties\":{\"description\":\"Superconducting Circuits + Quantum Computing Systems\",\"providerType\":\"qe\",\"company\":\"Quantum + Circuits, Inc.\",\"managedApplication\":{\"publisherId\":\"quantumcircuitsinc1598045891596\",\"offerId\":\"qci-aq\"},\"targets\":[{\"id\":\"qci.machine1\",\"name\":\"Machine + 1\",\"description\":\"8-qubit quantum computing system with real-time control + flow capability.\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"qci.simulator\",\"name\":\"AquSim\",\"description\":\"8-qubit + noise-free simulator.\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]},{\"id\":\"qci.simulator.noisy\",\"name\":\"AquSim-N\",\"description\":\"8-qubit + simulator that incorporates QCI's gate and measurement performance\",\"acceptedDataFormats\":[\"qci.qcdl.v1\",\"qci.qir.v1\"],\"acceptedContentEncodings\":[\"identity\"]}],\"skus\":[{\"id\":\"qci-syspreview\",\"version\":\"0.1.0\",\"name\":\"System + Preview\",\"description\":\"A metered pricing preview of QCI's Systems and + Simulators\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Integration + testing plan for Microsoft\"},{\"id\":\"quota\",\"value\":\"1000 jobs per + month\"},{\"id\":\"price\",\"value\":\"\"}]},{\"id\":\"qci-syspreview-free\",\"version\":\"0.1.0\",\"name\":\"System + Preview Free\",\"description\":\"A free preview of QCI's Systems and Simulators\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Integration + testing plan for Microsoft\"},{\"id\":\"quota\",\"value\":\"Unlimited jobs\"},{\"id\":\"price\",\"value\":\"\"}]},{\"id\":\"qci-freepreview\",\"version\":\"0.1.0\",\"name\":\"System + Preview (Free)\",\"description\":\"A free preview of QCI's simulators and + quantum systems.\",\"autoAdd\":false,\"targets\":[\"qci.simulator\",\"qci.machine1\",\"qci.simulator.noisy\"],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Machine + 1 Quantum System and the AquSim Quantum Simulator\"},{\"id\":\"quota\",\"value\":\"1000 + jobs per month\"},{\"id\":\"price\",\"value\":\"\"}]}],\"quotaDimensions\":[{\"id\":\"jobcount\",\"scope\":\"Workspace\",\"quota\":1000,\"period\":\"Monthly\",\"name\":\"Job + Count\",\"description\":\"Number of jobs you can run in a month.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"quantinuum\",\"name\":\"Quantinuum\",\"properties\":{\"description\":\"Access + to Quantinuum trapped-ion systems\",\"providerType\":\"qe\",\"company\":\"Quantinuum\",\"managedApplication\":{\"publisherId\":\"quantinuumllc1640113159771\",\"offerId\":\"quantinuum-aq\"},\"targets\":[{\"id\":\"quantinuum.hqs-lt-s1\",\"name\":\"Quantinuum + H1-1\",\"description\":\"Quantinuum H1-1, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-1\",\"name\":\"Quantinuum + H1-1\",\"description\":\"Quantinuum H1-1, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2\",\"name\":\"Quantinuum + H1-2\",\"description\":\"Quantinuum H1-2, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-2\",\"name\":\"Quantinuum + H1-2\",\"description\":\"Quantinuum H1-2, Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt\",\"name\":\"Quantinuum + System Model: H1 Family\",\"description\":\"Quantinuum System Model H1 Family, + Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1\",\"name\":\"Quantinuum + System Model: H1 Family\",\"description\":\"Quantinuum System Model H1 Family, + Powered by Honeywell\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s1-apival\",\"name\":\"Quantinuum + H1-1 Syntax Checker\",\"description\":\"Quantinuum H1-1 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1sc\",\"name\":\"Quantinuum + H1-1 Syntax Checker\",\"description\":\"Quantinuum H1-1 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2-apival\",\"name\":\"Quantinuum + H1-2 Syntax Checker\",\"description\":\"Quantinuum H1-2 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2sc\",\"name\":\"Quantinuum + H1-2 Syntax Checker\",\"description\":\"Quantinuum H1-2 Syntax Checker\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s1-sim\",\"name\":\"Quantinuum + H1-1 Emulator\",\"description\":\"Quantinuum H1-1 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1e\",\"name\":\"Quantinuum + H1-1 Emulator\",\"description\":\"Quantinuum H1-1 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.hqs-lt-s2-sim\",\"name\":\"Quantinuum + H1-2 Emulator\",\"description\":\"Quantinuum H1-2 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2e\",\"name\":\"Quantinuum + H1-2 Emulator\",\"description\":\"Quantinuum H1-2 Emulator\",\"acceptedDataFormats\":[\"honeywell.openqasm.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1sc-preview\",\"name\":\"Quantinuum + H1-1 Syntax Checker Preview\",\"description\":\"Quantinuum H1-1 Syntax Checker + Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2sc-preview\",\"name\":\"Quantinuum + H1-2 Syntax Checker Preview\",\"description\":\"Quantinuum H1-2 Syntax Checker + Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-1e-preview\",\"name\":\"Quantinuum + H1-1 Emulator Preview\",\"description\":\"Quantinuum H1-1 Emulator Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.sim.h1-2e-preview\",\"name\":\"Quantinuum + H1-2 Emulator Preview\",\"description\":\"Quantinuum H1-2 Emulator Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-1-preview\",\"name\":\"Quantinuum + H1-1 Preview\",\"description\":\"Quantinuum H1-1 Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"quantinuum.qpu.h1-2-preview\",\"name\":\"Quantinuum + H1-2 Preview\",\"description\":\"Quantinuum H1-2 Preview\",\"acceptedDataFormats\":[\"honeywell.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"credits1\",\"version\":\"1.0.0\",\"name\":\"Azure + Quantum Credits\",\"description\":\"The Azure Quantum Credits program provides + sponsored access to Quantinuum hardware through Azure. You will not be charged + for usage created under the credits program, up to the limit of your credit + grant.\",\"autoAdd\":true,\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"System + Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum + System Model H1, Powered by Honeywell\"},{\"id\":\"limits\",\"value\":\"Up + to $500 of Quantinuum compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.\"}]},{\"id\":\"premium1\",\"version\":\"1.0.0\",\"name\":\"Premium\",\"description\":\"Monthly + subscription plan with 17K Quantinuum H-System Quantum Credits (HQCs) / month, + available through queue\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:QuantinuumAzureQuantumSupport@Quantinuum.com\",\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"17K H-System + Quantum Credits (HQCs) / month\"},{\"id\":\"price\",\"value\":\"$ 175,000 + USD / Month\"}]},{\"id\":\"standard1\",\"version\":\"1.0.0\",\"name\":\"Standard\",\"description\":\"Monthly + subscription plan with 10K Quantinuum H-System quantum credits (HQCs) / month, + available through queue\",\"autoAdd\":false,\"restrictedAccessUri\":\"mailto:QuantinuumAzureQuantumSupport@Quantinuum.com\",\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\"],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"10K H-System + Quantum Credits (HQCs) / month\"},{\"id\":\"price\",\"value\":\"$ 125,000 + USD / Month\"}]},{\"id\":\"test1\",\"version\":\"1.0.0\",\"name\":\"Partner + Access\",\"description\":\"Charge-free access to Quantinuum System Model H1 + for Azure integration verification\",\"autoAdd\":false,\"targets\":[\"quantinuum.hqs-lt-s1\",\"quantinuum.hqs-lt-s1-apival\",\"quantinuum.hqs-lt-s2\",\"quantinuum.hqs-lt-s2-apival\",\"quantinuum.hqs-lt-s1-sim\",\"quantinuum.hqs-lt-s2-sim\",\"quantinuum.hqs-lt\",\"quantinuum.qpu.h1-1\",\"quantinuum.sim.h1-1sc\",\"quantinuum.qpu.h1-2\",\"quantinuum.sim.h1-2sc\",\"quantinuum.sim.h1-1e\",\"quantinuum.sim.h1-2e\",\"quantinuum.qpu.h1\",\"quantinuum.sim.h1-1sc-preview\",\"quantinuum.sim.h1-2sc-preview\",\"quantinuum.sim.h1-1e-preview\",\"quantinuum.sim.h1-2e-preview\",\"quantinuum.qpu.h1-1-preview\",\"quantinuum.qpu.h1-2-preview\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Quantinuum + System Model H1 Syntax Checker
Quantinuum System Model H1 Emulator
Quantinuum System Model H1\"},{\"id\":\"limits\",\"value\":\"No limit for + integration testing\"},{\"id\":\"price\",\"value\":\"Free for validation\"}]}],\"quotaDimensions\":[{\"id\":\"hqc\",\"scope\":\"Subscription\",\"quota\":40,\"period\":\"Infinite\",\"name\":\"H-System + Quantum Credit (HQC)\",\"description\":\"H-System Quantum Credits (HQCs) are + used to calculate the cost of a job. See Quantinuum documentation for more + information.\",\"unit\":\"HQC\",\"unitPlural\":\"HQC's\"},{\"id\":\"ehqc\",\"scope\":\"Subscription\",\"quota\":400,\"period\":\"Infinite\",\"name\":\"Emulator + HQCs (eHQC)\",\"description\":\"Quantinuum Emulator H-System Quantum Credits + (eHQCs) are used for submission to the emulator.\",\"unit\":\"EHQC\",\"unitPlural\":\"EHQC's\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"limits\",\"name\":\"Limits\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"rigetti\",\"name\":\"Rigetti + Quantum\",\"properties\":{\"description\":\"Run quantum programs on Rigetti's + superconducting qubit-based quantum processors.\",\"providerType\":\"qe\",\"company\":\"Rigetti + Computing\",\"managedApplication\":{\"publisherId\":\"rigetticoinc1644276861431\",\"offerId\":\"rigetti-aq\"},\"targets\":[{\"id\":\"rigetti.sim.qvm\",\"name\":\"QVM\",\"description\":\"Simulate + Quil and QIR programs on the open-source Quantum Virtual Machine.\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-11\",\"name\":\"Aspen-11\",\"description\":\"A + 40-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-m-2\",\"name\":\"Aspen-M-2\",\"description\":\"An + 80-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]},{\"id\":\"rigetti.qpu.aspen-m-3\",\"name\":\"Aspen-M-3\",\"description\":\"An + 80-Qubit QPU\",\"acceptedDataFormats\":[\"rigetti.quil.v1\",\"rigetti.qir.v1\"],\"acceptedContentEncodings\":[\"gzip\",\"identity\"]}],\"skus\":[{\"id\":\"rigetti-private-beta-metered\",\"version\":\"0.0.0\",\"name\":\"Metered + Private Preview\",\"description\":\"Limited-time free access to Rigetti quantum + computers with the ability to see your utilization.\",\"autoAdd\":false,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"This plan has no quota.\"},{\"id\":\"price\",\"value\":\"This + plan is free.\"}]},{\"id\":\"rigetti-pay-as-you-go\",\"version\":\"0.0.0\",\"name\":\"Pay + As You Go\",\"description\":\"Pay-as-you-go access to Rigetti quantum computers.\",\"autoAdd\":false,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"This plan has no quota.\"},{\"id\":\"price\",\"value\":\"$0.02 + per 10 milliseconds (rounded up) of QPU execution time.\"}]},{\"id\":\"azure-quantum-credits\",\"version\":\"0.0.0\",\"name\":\"Azure + Quantum Credits\",\"description\":\"Pay with Azure credits for access to Rigetti + quantum computers.\",\"autoAdd\":true,\"targets\":[\"rigetti.sim.qvm\",\"rigetti.qpu.aspen-11\",\"rigetti.qpu.aspen-m-2\",\"rigetti.qpu.aspen-m-3\"],\"quotaDimensions\":[{\"id\":\"provider-credit\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"features\",\"value\":\"Learn more about + Rigetti Targets\"},{\"id\":\"quota\",\"value\":\"$500 worth of Rigetti + compute, unless you have received an additional project-based grant.

While availability + lasts, credits must be used within 6 months.

Learn more about quota for credits.\"},{\"id\":\"price\",\"value\":\"Free, + up to the granted value of your credits.
Credits consumed on the base + of $0.02 (credits) per 10 milliseconds (rounded up) of QPU execution time.\"}]}],\"quotaDimensions\":[{\"id\":\"provider-credit\",\"scope\":\"Subscription\",\"quota\":25000,\"period\":\"Infinite\",\"name\":\"QPU + Credits\",\"description\":\"One credit covers 10 milliseconds of QPU execution + time, which normally costs $0.02.\",\"unit\":\"credit\",\"unitPlural\":\"credits\"}],\"pricingDimensions\":[{\"id\":\"features\",\"name\":\"Features\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Pricing\"}]}},{\"id\":\"toshiba\",\"name\":\"SQBM+ + Cloud on Azure Quantum\",\"properties\":{\"description\":\"A GPU-powered ISING + machine featuring the Simulated Bifurcation algorithm inspired by Toshiba's + research on quantum computing.\",\"providerType\":\"qio\",\"company\":\"Toshiba + Digital Solutions Corporation\",\"managedApplication\":{\"publisherId\":\"2812187\",\"offerId\":\"toshiba-aq\"},\"targets\":[{\"id\":\"toshiba.sbm.ising\",\"name\":\"Ising + solver\",\"description\":\"Originated from research on quantum bifurcation + machines, the SQBM+ is a practical and ready-to-use ISING machine that solves + large-scale \\\"combinatorial optimization problems\\\" at high speed.\",\"acceptedDataFormats\":[\"microsoft.qio.v2\"],\"acceptedContentEncodings\":[\"gzip\"]}],\"skus\":[{\"id\":\"toshiba-solutionseconds\",\"version\":\"1.0.1\",\"name\":\"Pay + As You Go\",\"description\":\"This is the only plan for using SQBM+ in Azure + Quantum Private Preview.\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"No + limit\"},{\"id\":\"price\",\"value\":\"This plan is available for free during + private preview.\"}]},{\"id\":\"learn_and_develop\",\"version\":\"1.0.1\",\"name\":\"Learn + & Develop\",\"description\":\"Learn and develop with SQBM+ (not for operational + use).\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"quotaDimensions\":[{\"id\":\"learn_and_develop_concurrent_jobs\",\"scope\":\"Workspace\"},{\"id\":\"learn_and_develop_job_execution_time\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"

Up + to 1 concurrent jobs.

1 hour of compute per month.

\"},{\"id\":\"price\",\"value\":\"This + value loaded from partner center.\"}]},{\"id\":\"performance_at_scale\",\"version\":\"1.0.1\",\"name\":\"Performance + at scale\",\"description\":\"Deploy world-class SQBM+ solutions.\",\"autoAdd\":false,\"targets\":[\"toshiba.sbm.ising\"],\"quotaDimensions\":[{\"id\":\"performance_at_scale_concurrent_jobs\",\"scope\":\"Workspace\"},{\"id\":\"performance_at_scale_job_execution_time\",\"scope\":\"Subscription\"}],\"pricingDetails\":[{\"id\":\"targets\",\"value\":\"toshiba.sbm.ising\"},{\"id\":\"quota\",\"value\":\"

Up + to 3 concurrent jobs.

2,500 hours of compute per month.

\"},{\"id\":\"price\",\"value\":\"This + value loaded from partner center.\"}]}],\"quotaDimensions\":[{\"id\":\"learn_and_develop_concurrent_jobs\",\"scope\":\"Workspace\",\"quota\":1,\"name\":\"Concurrent + jobs\",\"description\":\"The number of jobs that you can submit within a single + workspace at the same time.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"},{\"id\":\"learn_and_develop_job_execution_time\",\"scope\":\"Subscription\",\"quota\":1,\"period\":\"Monthly\",\"name\":\"Computing + hours per month\",\"description\":\"Computing hours within a subscription + per month.\",\"unit\":\"hour\",\"unitPlural\":\"hours\"},{\"id\":\"performance_at_scale_concurrent_jobs\",\"scope\":\"Workspace\",\"quota\":3,\"name\":\"Concurrent + jobs\",\"description\":\"The number of jobs that you can submit within a single + workspace at the same time.\",\"unit\":\"job\",\"unitPlural\":\"jobs\"},{\"id\":\"performance_at_scale_job_execution_time\",\"scope\":\"Subscription\",\"quota\":2500,\"period\":\"Monthly\",\"name\":\"Computing + hours per month\",\"description\":\"Computing hours within a subscription + per month.\",\"unit\":\"hour\",\"unitPlural\":\"hours\"}],\"pricingDimensions\":[{\"id\":\"targets\",\"name\":\"Targets + available\"},{\"id\":\"quota\",\"name\":\"Quota\"},{\"id\":\"price\",\"name\":\"Price + per month\"}]}}]}" + headers: + cache-control: + - no-cache + content-length: + - '41041' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:37 GMT + expires: + - '-1' + mise-correlation-id: + - 8a259e7c-d048-4f00-8f47-c4f23da77e03 + pragma: + - no-cache + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + set-cookie: + - ARRAffinity=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ARRAffinitySameSite=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;SameSite=None;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + path=/; secure + - ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + samesite=none; path=/; secure + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-azure-ref: + - 0Ah7PYwAAAADUroH2IYYnTK4Yg9D+aIdlUEhMMzBFREdFMDMxMwBlNDgyMjUzYi05ZTA1LTQwNWUtYTgzZi01ODZlZTFkNTUzZTQ= + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current","name":"credits1","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"quantinuumllc1640113159771","product":"quantinuum-aq","plan":"credits1","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_QUANTINUUMLLC1640113159771%253a24QUANTINUUM%253a2DAQ%253a24CREDITS1%253a24U3AGC77IHGZ5FLJYZ6QWF357B7LQHG6PW5CSVK7VKS2YGVWO4OBIOCCOCSXJEEP6BMMDOPFM4ETZZYATWBPM2EFN4YT4KWM6QDFMTOY.txt","privacyPolicyLink":"https://www.quantinuum.com/privacy-statement","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-23T23:53:41.1664378Z","signature":"5Y32HTGUQ3SZ7DXZFNY2W6WXBFKK4FCY4G5BAV5XRFVTEBD7FAETP4WUDZBDQTE5JEU4EO5OSJ3RFGVNOTWYFW64BBU7LCP6WCYV4JI","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-23T23:53:41.2602379+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-23T23:53:41.2602379+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1440' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:40 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/quantumcircuitsinc1598045891596/offers/qci-aq/plans/qci-freepreview/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/quantumcircuitsinc1598045891596/offers/qci-aq/plans/qci-freepreview/agreements/current","name":"qci-freepreview","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"quantumcircuitsinc1598045891596","product":"qci-aq","plan":"qci-freepreview","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_QUANTUMCIRCUITSINC1598045891596%253a24QCI%253a2DAQ%253a24QCI%253a2DFREEPREVIEW%253a24PP3GLE327RQ6PXCFKVKKUIHX2KTKAPSMYHMY4RTIDVZNPA5MI4TAS4E3EMRM43OT3R3PWF5I7NG2Z2AYJYYMAIATBW7A256UYHC34CY.txt","privacyPolicyLink":"https://www.quantumcircuits.com/privacy-policy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-23T23:53:44.0959179Z","signature":"B2YT2LIQZGTIQYZOVHBBM5Z3QBSWXLSESYUH6AACOQXUYR7WPLYZ6K4YTNUEN6OWG4GPDEN4EQQDV6ETWDHGEUA7MSH4CYGIZVRUPFQ","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-23T23:53:44.4709855+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-23T23:53:44.4709855+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1470' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:44 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/rigetticoinc1644276861431/offers/rigetti-aq/plans/azure-quantum-credits/agreements/current","name":"azure-quantum-credits","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"rigetticoinc1644276861431","product":"rigetti-aq","plan":"azure-quantum-credits","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_RIGETTICOINC1644276861431%253a24RIGETTI%253a2DAQ%253a24AZURE%253a2DQUANTUM%253a2DCREDITS%253a24H35R3FYQURHQDNSLAZ4YCHIHABQ4NR4UI66LMJ3K53EHCQWZJMC3BLGZODKSAMOQ4ZI5CVO37XQXKFBQ3YWK444S7B3XGBK67JHVZNI.txt","privacyPolicyLink":"https://www.rigetti.com/privacy-policy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-23T23:53:46.8260086Z","signature":"WLVIWIGCA55LLZXVGE2HMZB4RUDK2WFDYJCEBCHOK2ZXEYQBEZ4RUPE3B4DDZSZTF4E2KS6VXSO237JCY2DXI7GOWB7FHR6UKFQTOEA","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-23T23:53:46.8729165+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-23T23:53:46.8729165+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1486' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:46 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/ionqinc1582730893633/offers/ionq-aq/plans/pay-as-you-go-cred/agreements/current","name":"pay-as-you-go-cred","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"ionqinc1582730893633","product":"ionq-aq","plan":"pay-as-you-go-cred","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_IONQINC1582730893633%253a24IONQ%253a2DAQ%253a24PAY%253a2DAS%253a2DYOU%253a2DGO%253a2DCRED%253a247ODGLEAK7RQISNHUEU4KJYVC6QLVZF5IANNQFGBHOKJMXWIW3OPRUADLB63ROSGS5FVYSHLINGX5BK7GF7Y2ZO24HKBHSPKMXBHFBAQ.txt","privacyPolicyLink":"https://ionq.com/privacy","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-23T23:53:49.5359409Z","signature":"6G36P3GWN52X7G2MFGD7OHF47VWVYHZCR65XOL6WWUKRTXSVYKSGTKTRYHGIJZMXQMZPERJNSGMXKCM66MJBPT7JGKLW3PYSXIBLZRY","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-23T23:53:49.6921817+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-23T23:53:49.6921817+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1448' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:49 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-marketplaceordering/1.1.0 Python/3.10.6 + (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/virtualmachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current?api-version=2021-01-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/quantinuumllc1640113159771/offers/quantinuum-aq/plans/credits1/agreements/current","name":"credits1","type":"Microsoft.MarketplaceOrdering/offertypes","properties":{"publisher":"quantinuumllc1640113159771","product":"quantinuum-aq","plan":"credits1","licenseTextLink":"https://mpcprodsa.blob.core.windows.net/legalterms/3E5ED_legalterms_QUANTINUUMLLC1640113159771%253a24QUANTINUUM%253a2DAQ%253a24CREDITS1%253a24U3AGC77IHGZ5FLJYZ6QWF357B7LQHG6PW5CSVK7VKS2YGVWO4OBIOCCOCSXJEEP6BMMDOPFM4ETZZYATWBPM2EFN4YT4KWM6QDFMTOY.txt","privacyPolicyLink":"https://www.quantinuum.com/privacy-statement","marketplaceTermsLink":"https://mpcprodsa.blob.core.windows.net/marketplaceterms/3EDEF_marketplaceterms_AZUREAPPLICATION%253a24OF7TIMHFEMPZHRBYEO3SVLC7Q2MPXXAASJ5BO2FUY4UC6EZCN5TIL2KIGTA7WI2CSM3WV4L7QMPNRYPE2I7BOCM34RGOL3XTC6ADIMI.txt","retrieveDatetime":"2023-01-23T23:53:52.2083793Z","signature":"HO7LUGMLF2BYUTPYEHAKL3YYEYWCNJZJ74MXNUU4F7Y6UJRN34SZOS4MWA6BMSWAOF7MY5MOV4ALHGARHTU3HFMCWN4ZAX7XQBMZ5OQ","accepted":true},"systemData":{"createdBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","createdByType":"ManagedIdentity","createdAt":"2023-01-23T23:53:52.270862+00:00","lastModifiedBy":"677fc922-91d0-4bf6-9b06-4274d319a0fa","lastModifiedByType":"ManagedIdentity","lastModifiedAt":"2023-01-23T23:53:52.270862+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '1438' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:51 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace create + Connection: + - keep-alive + ParameterSetName: + - -g -w -l -a -r + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts?api-version=2022-09-01 + response: + body: + string: '{"value":[{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","name":"vwjonesstorage2","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2021-09-21T22:04:47.1374328Z","key2":"2021-09-21T22:04:47.1374328Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-09-21T22:04:47.0124593Z","primaryEndpoints":{"blob":"https://vwjonesstorage2.blob.core.windows.net/","queue":"https://vwjonesstorage2.queue.core.windows.net/","table":"https://vwjonesstorage2.table.core.windows.net/","file":"https://vwjonesstorage2.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage3","name":"vwjonesstorage3","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-08-11T18:41:05.2371860Z","key2":"2022-08-11T18:41:05.2371860Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-11T18:41:05.2371860Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-11T18:41:05.2371860Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-08-11T18:41:05.0652888Z","primaryEndpoints":{"blob":"https://vwjonesstorage3.blob.core.windows.net/","queue":"https://vwjonesstorage3.queue.core.windows.net/","table":"https://vwjonesstorage3.table.core.windows.net/","file":"https://vwjonesstorage3.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage33310","name":"vwjonesstorage33310","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-12-13T02:10:06.0148695Z","key2":"2022-12-13T02:10:06.0148695Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-12-13T02:10:06.0148695Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-12-13T02:10:06.0148695Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-12-13T02:10:05.8273595Z","primaryEndpoints":{"blob":"https://vwjonesstorage33310.blob.core.windows.net/","queue":"https://vwjonesstorage33310.queue.core.windows.net/","table":"https://vwjonesstorage33310.table.core.windows.net/","file":"https://vwjonesstorage33310.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage4","name":"vwjonesstorage4","type":"Microsoft.Storage/storageAccounts","location":"westus","tags":{},"properties":{"keyCreationTime":{"key1":"2022-08-24T18:30:25.3831084Z","key2":"2022-08-24T18:30:25.3831084Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-24T18:30:25.3987025Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-24T18:30:25.3987025Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-08-24T18:30:25.2580954Z","primaryEndpoints":{"blob":"https://vwjonesstorage4.blob.core.windows.net/","queue":"https://vwjonesstorage4.queue.core.windows.net/","table":"https://vwjonesstorage4.table.core.windows.net/","file":"https://vwjonesstorage4.file.core.windows.net/"},"primaryLocation":"westus","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"StorageV2","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage5","name":"vwjonesstorage5","type":"Microsoft.Storage/storageAccounts","location":"westus2","tags":{},"properties":{"dnsEndpointType":"Standard","defaultToOAuthAuthentication":false,"publicNetworkAccess":"Enabled","keyCreationTime":{"key1":"2022-08-25T21:57:16.1412273Z","key2":"2022-08-25T21:57:16.1412273Z"},"allowCrossTenantReplication":true,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_2","allowBlobPublicAccess":true,"allowSharedKeyAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"requireInfrastructureEncryption":false,"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-25T21:57:16.5630689Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-08-25T21:57:16.5630689Z"}},"keySource":"Microsoft.Storage"},"accessTier":"Hot","provisioningState":"Succeeded","creationTime":"2022-08-25T21:57:16.0474739Z","primaryEndpoints":{"dfs":"https://vwjonesstorage5.dfs.core.windows.net/","web":"https://vwjonesstorage5.z5.web.core.windows.net/","blob":"https://vwjonesstorage5.blob.core.windows.net/","queue":"https://vwjonesstorage5.queue.core.windows.net/","table":"https://vwjonesstorage5.table.core.windows.net/","file":"https://vwjonesstorage5.file.core.windows.net/"},"primaryLocation":"westus2","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage7","name":"vwjonesstorage7","type":"Microsoft.Storage/storageAccounts","location":"eastus2euap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-09-29T22:32:06.2588030Z","key2":"2022-09-29T22:32:06.2588030Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:32:06.7900691Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:32:06.7900691Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-09-29T22:32:06.1806703Z","primaryEndpoints":{"blob":"https://vwjonesstorage7.blob.core.windows.net/","queue":"https://vwjonesstorage7.queue.core.windows.net/","table":"https://vwjonesstorage7.table.core.windows.net/","file":"https://vwjonesstorage7.file.core.windows.net/"},"primaryLocation":"eastus2euap","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage6","name":"vwjonesstorage6","type":"Microsoft.Storage/storageAccounts","location":"centraluseuap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-09-29T22:13:05.8017810Z","key2":"2022-09-29T22:13:05.8017810Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:13:06.3017835Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-09-29T22:13:06.3017835Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-09-29T22:13:05.7392784Z","primaryEndpoints":{"blob":"https://vwjonesstorage6.blob.core.windows.net/","queue":"https://vwjonesstorage6.queue.core.windows.net/","table":"https://vwjonesstorage6.table.core.windows.net/","file":"https://vwjonesstorage6.file.core.windows.net/"},"primaryLocation":"centraluseuap","statusOfPrimary":"available"}},{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstoragecanary","name":"vwjonesstoragecanary","type":"Microsoft.Storage/storageAccounts","location":"centraluseuap","tags":{},"properties":{"keyCreationTime":{"key1":"2022-10-27T21:45:38.3454788Z","key2":"2022-10-27T21:45:38.3454788Z"},"allowCrossTenantReplication":false,"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-10-27T21:45:38.3454788Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2022-10-27T21:45:38.3454788Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2022-10-27T21:45:38.2829751Z","primaryEndpoints":{"blob":"https://vwjonesstoragecanary.blob.core.windows.net/","queue":"https://vwjonesstoragecanary.queue.core.windows.net/","table":"https://vwjonesstoragecanary.table.core.windows.net/","file":"https://vwjonesstoragecanary.file.core.windows.net/"},"primaryLocation":"centraluseuap","statusOfPrimary":"available"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '10770' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:52 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-original-request-ids: + - d5176945-61e0-4c6b-b031-eac48aca78ee + - 536008ae-bb8f-4590-99c7-4442b054332a + - e0b566c6-7e8d-4037-bec5-324e35d5de02 + - 2dd73991-6cba-4cc6-b429-0f35832064fa + - f0ce29fd-53bd-4b2e-b5a3-cc36bd92ec2c + status: + code: 200 + message: OK +- request: + body: '{"properties": {"template": {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "parameters": {"quantumWorkspaceName": {"type": + "string", "metadata": {"description": "Quantum Workspace Name"}}, "location": + {"type": "string", "metadata": {"description": "Workspace Location"}}, "tags": + {"type": "object", "defaultValue": {}, "metadata": {"description": "Tags for + this workspace"}}, "providers": {"type": "array", "metadata": {"description": + "A list of Providers for this workspace"}}, "storageAccountName": {"type": "string", + "metadata": {"description": "Storage account short name"}}, "storageAccountId": + {"type": "string", "metadata": {"description": "Storage account ID (path)"}}, + "storageAccountLocation": {"type": "string", "metadata": {"description": "Storage + account location"}}, "storageAccountSku": {"type": "string", "metadata": {"description": + "Storage account SKU"}}, "storageAccountKind": {"type": "string", "metadata": + {"description": "Kind of storage account"}}, "storageAccountDeploymentName": + {"type": "string", "metadata": {"description": "Deployment name for role assignment + operation"}}}, "functions": [], "variables": {}, "resources": [{"type": "Microsoft.Quantum/workspaces", + "apiVersion": "2019-11-04-preview", "name": "[parameters(''quantumWorkspaceName'')]", + "location": "[parameters(''location'')]", "tags": "[parameters(''tags'')]", + "identity": {"type": "SystemAssigned"}, "properties": {"providers": "[parameters(''providers'')]", + "storageAccount": "[parameters(''storageAccountId'')]"}}, {"apiVersion": "2019-10-01", + "name": "[parameters(''storageAccountDeploymentName'')]", "type": "Microsoft.Resources/deployments", + "dependsOn": ["[resourceId(''Microsoft.Quantum/Workspaces'', parameters(''quantumWorkspaceName''))]"], + "properties": {"mode": "Incremental", "template": {"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "resources": [{"apiVersion": "2019-06-01", "name": + "[parameters(''storageAccountName'')]", "location": "[parameters(''storageAccountLocation'')]", + "type": "Microsoft.Storage/storageAccounts", "sku": {"name": "[parameters(''storageAccountSku'')]"}, + "kind": "[parameters(''storageAccountKind'')]", "resources": [{"name": "default", + "type": "fileServices", "apiVersion": "2019-06-01", "dependsOn": ["[parameters(''storageAccountId'')]"], + "properties": {"cors": {"corsRules": [{"allowedOrigins": ["*"], "allowedHeaders": + ["*"], "allowedMethods": ["GET", "HEAD", "OPTIONS", "POST", "PUT"], "exposedHeaders": + ["*"], "maxAgeInSeconds": 180}]}}}]}, {"apiVersion": "2020-04-01-preview", "name": + "[concat(parameters(''storageAccountName''), ''/Microsoft.Authorization/'', + guid(reference(concat(''Microsoft.Quantum/Workspaces/'', parameters(''quantumWorkspaceName'')), + ''2019-11-04-preview'', ''Full'').identity.principalId))]", "type": "Microsoft.Storage/storageAccounts/providers/roleAssignments", + "location": "[parameters(''storageAccountLocation'')]", "properties": {"roleDefinitionId": + "[resourceId(''Microsoft.Authorization/roleDefinitions'', ''b24988ac-6180-42a0-ab88-20f7382dd24c'')]", + "principalId": "[reference(concat(''Microsoft.Quantum/Workspaces/'', parameters(''quantumWorkspaceName'')), + ''2019-11-04-preview'', ''Full'').identity.principalId]", "principalType": "ServicePrincipal"}, + "dependsOn": ["[parameters(''storageAccountId'')]"]}]}}}], "outputs": {}}, "parameters": + {"quantumWorkspaceName": {"value": "e2e-test-w9154517"}, "location": {"value": + "eastus"}, "tags": {"value": {}}, "providers": {"value": [{"providerId": "qci", + "providerSku": "qci-freepreview"}, {"providerId": "rigetti", "providerSku": + "azure-quantum-credits"}, {"providerId": "ionq", "providerSku": "pay-as-you-go-cred"}, + {"providerId": "Microsoft", "providerSku": "DZH3178M639F"}, {"providerId": "microsoft-qc", + "providerSku": "learn-and-develop"}, {"providerId": "quantinuum", "providerSku": + "credits1"}]}, "storageAccountName": {"value": "vwjonesstorage2"}, "storageAccountId": + {"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"}, + "storageAccountLocation": {"value": "eastus"}, "storageAccountSku": {"value": + "Standard_LRS"}, "storageAccountKind": {"value": "Storage"}, "storageAccountDeploymentName": + {"value": "Microsoft.StorageAccount-23-Jan-2023-23-53-52"}}, "mode": "Incremental"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '4407' + Content-Type: + - application/json + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2021-04-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w9154517","name":"Microsoft.AzureQuantum-e2e-test-w9154517","type":"Microsoft.Resources/deployments","properties":{"templateHash":"6354453805046911057","parameters":{"quantumWorkspaceName":{"type":"String","value":"e2e-test-w9154517"},"location":{"type":"String","value":"eastus"},"tags":{"type":"Object","value":{}},"providers":{"type":"Array","value":[{"providerId":"qci","providerSku":"qci-freepreview"},{"providerId":"rigetti","providerSku":"azure-quantum-credits"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred"},{"providerId":"Microsoft","providerSku":"DZH3178M639F"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop"},{"providerId":"quantinuum","providerSku":"credits1"}]},"storageAccountName":{"type":"String","value":"vwjonesstorage2"},"storageAccountId":{"type":"String","value":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},"storageAccountLocation":{"type":"String","value":"eastus"},"storageAccountSku":{"type":"String","value":"Standard_LRS"},"storageAccountKind":{"type":"String","value":"Storage"},"storageAccountDeploymentName":{"type":"String","value":"Microsoft.StorageAccount-23-Jan-2023-23-53-52"}},"mode":"Incremental","provisioningState":"Accepted","timestamp":"2023-01-23T23:53:55.5261362Z","duration":"PT0.0000859S","correlationId":"6d789773-7724-47ae-a1c4-a7ee02bca3d6","providers":[{"namespace":"Microsoft.Quantum","resourceTypes":[{"resourceType":"workspaces","locations":["eastus"]}]},{"namespace":"Microsoft.Resources","resourceTypes":[{"resourceType":"deployments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/Workspaces/e2e-test-w9154517","resourceType":"Microsoft.Quantum/Workspaces","resourceName":"e2e-test-w9154517"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","resourceType":"Microsoft.Quantum/workspaces","resourceName":"e2e-test-w9154517","apiVersion":"2019-11-04-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.StorageAccount-23-Jan-2023-23-53-52","resourceType":"Microsoft.Resources/deployments","resourceName":"Microsoft.StorageAccount-23-Jan-2023-23-53-52"}]}}' + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w9154517/operationStatuses/08585270888509999263?api-version=2021-04-01 + cache-control: + - no-cache + content-length: + - '2607' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:55 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:53:55 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:54:25 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:54:56 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:55:25 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:55:55 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:56:25 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:56:55 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:57:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:57:56 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:58:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:58:56 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:59:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 23 Jan 2023 23:59:56 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Running"}' + headers: + cache-control: + - no-cache + content-length: + - '20' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:00:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08585270888509999263?api-version=2021-04-01 + response: + body: + string: '{"status":"Succeeded"}' + headers: + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:00:57 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-azure-mgmt-resource/21.1.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2021-04-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.AzureQuantum-e2e-test-w9154517","name":"Microsoft.AzureQuantum-e2e-test-w9154517","type":"Microsoft.Resources/deployments","properties":{"templateHash":"6354453805046911057","parameters":{"quantumWorkspaceName":{"type":"String","value":"e2e-test-w9154517"},"location":{"type":"String","value":"eastus"},"tags":{"type":"Object","value":{}},"providers":{"type":"Array","value":[{"providerId":"qci","providerSku":"qci-freepreview"},{"providerId":"rigetti","providerSku":"azure-quantum-credits"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred"},{"providerId":"Microsoft","providerSku":"DZH3178M639F"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop"},{"providerId":"quantinuum","providerSku":"credits1"}]},"storageAccountName":{"type":"String","value":"vwjonesstorage2"},"storageAccountId":{"type":"String","value":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},"storageAccountLocation":{"type":"String","value":"eastus"},"storageAccountSku":{"type":"String","value":"Standard_LRS"},"storageAccountKind":{"type":"String","value":"Storage"},"storageAccountDeploymentName":{"type":"String","value":"Microsoft.StorageAccount-23-Jan-2023-23-53-52"}},"mode":"Incremental","provisioningState":"Succeeded","timestamp":"2023-01-24T00:00:46.1976076Z","duration":"PT6M50.6715573S","correlationId":"6d789773-7724-47ae-a1c4-a7ee02bca3d6","providers":[{"namespace":"Microsoft.Quantum","resourceTypes":[{"resourceType":"workspaces","locations":["eastus"]}]},{"namespace":"Microsoft.Resources","resourceTypes":[{"resourceType":"deployments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/Workspaces/e2e-test-w9154517","resourceType":"Microsoft.Quantum/Workspaces","resourceName":"e2e-test-w9154517"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","resourceType":"Microsoft.Quantum/workspaces","resourceName":"e2e-test-w9154517","apiVersion":"2019-11-04-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Resources/deployments/Microsoft.StorageAccount-23-Jan-2023-23-53-52","resourceType":"Microsoft.Resources/deployments","resourceName":"Microsoft.StorageAccount-23-Jan-2023-23-53-52"}],"outputs":{},"outputResources":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/fileServices/default"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/providers/Microsoft.Authorization/roleAssignments/d550c41b-4c5d-5b1b-9b5c-059d9eb63549"}]}}' + headers: + cache-control: + - no-cache + content-length: + - '3345' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:00:57 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace set + Connection: + - keep-alive + ParameterSetName: + - -g -w -l + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517?api-version=2022-01-10-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","name":"e2e-test-w9154517","type":"microsoft.quantum/workspaces","location":"eastus","tags":{},"systemData":{"createdBy":"v-wjones@microsoft.com","createdByType":"User","createdAt":"2023-01-23T23:53:56.9639159Z","lastModifiedBy":"v-wjones@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-01-23T23:53:56.9639159Z"},"identity":{"principalId":"75b04db9-f07d-49f2-b05e-c8150e586215","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"providers":[{"providerId":"qci","providerSku":"qci-freepreview","applicationName":"e2e-test-w9154517-qci","provisioningState":"Succeeded"},{"providerId":"rigetti","providerSku":"azure-quantum-credits","applicationName":"e2e-test-w9154517-rigetti","provisioningState":"Succeeded","resourceUsageId":"7964fd5b-f302-4c93-bf64-d458ff733112"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred","applicationName":"e2e-test-w9154517-ionq","provisioningState":"Succeeded","resourceUsageId":"71b0823e-8eab-4e92-a036-28d137c0c498"},{"providerId":"Microsoft","providerSku":"DZH3178M639F","applicationName":"e2e-test-w9154517-Microsoft","provisioningState":"Succeeded"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop","applicationName":"e2e-test-w9154517-microsoft-qc","provisioningState":"Succeeded"},{"providerId":"quantinuum","providerSku":"credits1","applicationName":"e2e-test-w9154517-quantinuum","provisioningState":"Succeeded","resourceUsageId":"be341c87-5098-487f-b767-5a091fa55d3b"}],"provisioningState":"Succeeded","usable":"Yes","storageAccount":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","endpointUri":"https://e2e-test-w9154517.eastus.quantum.azure.com"}}' + headers: + cache-control: + - no-cache + content-length: + - '1906' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:00 GMT + etag: + - '"45004ef6-0000-0100-0000-63cf1f980000"' + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/providerStatus + response: + body: + string: '{"value":[{"id":"qci","currentAvailability":"Degraded","targets":[{"id":"qci.simulator","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://quantumcircuits.com"},{"id":"qci.machine1","currentAvailability":"Unavailable","averageQueueTime":1,"statusPage":"https://quantumcircuits.com"},{"id":"qci.simulator.noisy","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://quantumcircuits.com"}]},{"id":"rigetti","currentAvailability":"Degraded","targets":[{"id":"rigetti.sim.qvm","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-11","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null},{"id":"rigetti.qpu.aspen-m-2","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-m-3","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"}]},{"id":"ionq","currentAvailability":"Available","targets":[{"id":"ionq.qpu","currentAvailability":"Available","averageQueueTime":66466,"statusPage":"https://status.ionq.co"},{"id":"ionq.qpu.aria-1","currentAvailability":"Available","averageQueueTime":1029551,"statusPage":"https://status.ionq.co"},{"id":"ionq.simulator","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://status.ionq.co"}]},{"id":"Microsoft","currentAvailability":"Available","targets":[{"id":"microsoft.paralleltempering-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.paralleltempering.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.qmc.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"microsoft-qc","currentAvailability":"Available","targets":[{"id":"microsoft.estimator","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"quantinuum","currentAvailability":"Degraded","targets":[{"id":"quantinuum.hqs-lt-s1","currentAvailability":"Degraded","averageQueueTime":777,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-apival","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-apival","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-sim","currentAvailability":"Available","averageQueueTime":1061,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-sim","currentAvailability":"Available","averageQueueTime":29,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt","currentAvailability":"Degraded","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-1","currentAvailability":"Degraded","averageQueueTime":777,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1sc","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2sc","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1e","currentAvailability":"Available","averageQueueTime":1061,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2e","currentAvailability":"Available","averageQueueTime":29,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null}]}],"nextLink":null}' + headers: + connection: + - keep-alive + content-length: + - '4971' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:01 GMT + mise-correlation-id: + - bda7e6d7-9cbb-4081-acac-947286838bdf + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + ParameterSetName: + - -t --job-input-format -t --job-input-file --job-output-format -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517?api-version=2022-01-10-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","name":"e2e-test-w9154517","type":"microsoft.quantum/workspaces","location":"eastus","tags":{},"systemData":{"createdBy":"v-wjones@microsoft.com","createdByType":"User","createdAt":"2023-01-23T23:53:56.9639159Z","lastModifiedBy":"v-wjones@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-01-23T23:53:56.9639159Z"},"identity":{"principalId":"75b04db9-f07d-49f2-b05e-c8150e586215","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"providers":[{"providerId":"qci","providerSku":"qci-freepreview","applicationName":"e2e-test-w9154517-qci","provisioningState":"Succeeded"},{"providerId":"rigetti","providerSku":"azure-quantum-credits","applicationName":"e2e-test-w9154517-rigetti","provisioningState":"Succeeded","resourceUsageId":"7964fd5b-f302-4c93-bf64-d458ff733112"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred","applicationName":"e2e-test-w9154517-ionq","provisioningState":"Succeeded","resourceUsageId":"71b0823e-8eab-4e92-a036-28d137c0c498"},{"providerId":"Microsoft","providerSku":"DZH3178M639F","applicationName":"e2e-test-w9154517-Microsoft","provisioningState":"Succeeded"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop","applicationName":"e2e-test-w9154517-microsoft-qc","provisioningState":"Succeeded"},{"providerId":"quantinuum","providerSku":"credits1","applicationName":"e2e-test-w9154517-quantinuum","provisioningState":"Succeeded","resourceUsageId":"be341c87-5098-487f-b767-5a091fa55d3b"}],"provisioningState":"Succeeded","usable":"Yes","storageAccount":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","endpointUri":"https://e2e-test-w9154517.eastus.quantum.azure.com"}}' + headers: + cache-control: + - no-cache + content-length: + - '1906' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:01 GMT + etag: + - '"45004ef6-0000-0100-0000-63cf1f980000"' + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -t --job-input-format -t --job-input-file --job-output-format -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/listKeys?api-version=2022-09-01&$expand=kerb + response: + body: + string: '{"keys":[{"creationTime":"2021-09-21T22:04:47.1374328Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2021-09-21T22:04:47.1374328Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}' + headers: + cache-control: + - no-cache + content-length: + - '260' + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:02 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-resource-requests: + - '11999' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + ParameterSetName: + - -t --job-input-format -t --job-input-file --job-output-format -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2?api-version=2022-09-01 + response: + body: + string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","name":"vwjonesstorage2","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2021-09-21T22:04:47.1374328Z","key2":"2021-09-21T22:04:47.1374328Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-09-21T22:04:47.0124593Z","primaryEndpoints":{"blob":"https://vwjonesstorage2.blob.core.windows.net/","queue":"https://vwjonesstorage2.queue.core.windows.net/","table":"https://vwjonesstorage2.table.core.windows.net/","file":"https://vwjonesstorage2.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}}' + headers: + cache-control: + - no-cache + content-length: + - '1277' + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:02 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:02 GMT + x-ms-version: + - '2021-08-06' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04?restype=container + response: + body: + string: "\uFEFFContainerNotFoundThe + specified container does not exist.\nRequestId:9b5c8450-101e-0022-2a86-2f8712000000\nTime:2023-01-24T00:01:03.2610959Z" + headers: + content-length: + - '223' + content-type: + - application/xml + date: + - Tue, 24 Jan 2023 00:01:02 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-error-code: + - ContainerNotFound + x-ms-version: + - '2021-08-06' + status: + code: 404 + message: The specified container does not exist. +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:03 GMT + x-ms-version: + - '2021-08-06' + method: PUT + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04?restype=container + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Tue, 24 Jan 2023 00:01:03 GMT + etag: + - '"0x8DAFD9E157DC471"' + last-modified: + - Tue, 24 Jan 2023 00:01:03 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-version: + - '2021-08-06' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:03 GMT + x-ms-version: + - '2021-08-06' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04?restype=container + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Tue, 24 Jan 2023 00:01:03 GMT + etag: + - '"0x8DAFD9E157DC471"' + last-modified: + - Tue, 24 Jan 2023 00:01:03 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-default-encryption-scope: + - $account-encryption-key + x-ms-deny-encryption-scope-override: + - 'false' + x-ms-has-immutability-policy: + - 'false' + x-ms-has-legal-hold: + - 'false' + x-ms-immutable-storage-with-versioning-enabled: + - 'false' + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-version: + - '2021-08-06' + status: + code: 200 + message: OK +- request: + body: "DECLARE ro BIT[2]\r\n\r\nH 0\r\nCNOT 0 1\r\n\r\nMEASURE 0 ro[0]\r\nMEASURE + 1 ro[1]" + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '70' + Content-Type: + - application/octet-stream + If-None-Match: + - '*' + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-blob-type: + - BlockBlob + x-ms-date: + - Tue, 24 Jan 2023 00:01:03 GMT + x-ms-version: + - '2021-08-06' + method: PUT + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - wBue1+6CQmWpgL5BeUu42Q== + date: + - Tue, 24 Jan 2023 00:01:03 GMT + etag: + - '"0x8DAFD9E15A4582B"' + last-modified: + - Tue, 24 Jan 2023 00:01:03 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-content-crc64: + - csHCMZWsMR0= + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2021-08-06' + status: + code: 201 + message: Created +- request: + body: '{"containerUri": "https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04", + "inputDataFormat": "rigetti.quil.v1", "inputParams": {}, "providerId": "rigetti", + "target": "rigetti.sim.qvm", "outputDataFormat": "rigetti.quil-results.v1", + "tags": []}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '284' + Content-Type: + - application/json + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: PUT + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net:443/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"Unknown","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net:443/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":null,"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '881' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:04 GMT + mise-correlation-id: + - 5283d66c-2dba-4eff-aeda-c8e7b85c8b07 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=196l3rto%2FiErsoNKNuu3kdSa8bBExnzC0san3TA%2Bv78%3D&se=2023-01-28T00%3A01%3A05Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"Unknown","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=6aEX01kamP55lVCPYWgx4xKkIzxZKK0Za%2B%2Bc0U9vqEs%3D&se=2023-01-28T00%3A01%3A05Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":null,"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1256' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:05 GMT + mise-correlation-id: + - 4d8cffd1-9ba4-4ff5-b2df-8e8861d4ef2c + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=32jhKNasct4oafX1D1LRMQ%2F90fYGK65Bao%2BOI64QJlg%3D&se=2023-01-28T00%3A01%3A06Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=rmlQYOTTlqmLx9yThReHBUlT0W0POCKXabUIOik1TwQ%3D&se=2023-01-28T00%3A01%3A06Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1268' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:06 GMT + mise-correlation-id: + - a2216388-802d-4d91-9fbb-573b18929d54 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=32jhKNasct4oafX1D1LRMQ%2F90fYGK65Bao%2BOI64QJlg%3D&se=2023-01-28T00%3A01%3A06Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=rmlQYOTTlqmLx9yThReHBUlT0W0POCKXabUIOik1TwQ%3D&se=2023-01-28T00%3A01%3A06Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1268' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:06 GMT + mise-correlation-id: + - be00132a-e76e-4455-ab6a-623f4a8e864a + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=iERZEPoIeZnQyIXFoxbWbJpLeAFL%2BF2yyElhYzzFlqE%3D&se=2023-01-28T00%3A01%3A07Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=qbF6QCTF89gqkSioQ8UXR31qWZsGi4ILWUHCEYfsjvs%3D&se=2023-01-28T00%3A01%3A07Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1266' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:07 GMT + mise-correlation-id: + - 358e59c4-1dfc-46c8-be90-16092d0b61b2 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=iERZEPoIeZnQyIXFoxbWbJpLeAFL%2BF2yyElhYzzFlqE%3D&se=2023-01-28T00%3A01%3A07Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=qbF6QCTF89gqkSioQ8UXR31qWZsGi4ILWUHCEYfsjvs%3D&se=2023-01-28T00%3A01%3A07Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1266' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:07 GMT + mise-correlation-id: + - 7c4070b2-07b5-4812-a9e8-425476aa1270 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=q9afTepaJL8V8nkrL40XzXwyU1%2FXZfA4q7UR774Muds%3D&se=2023-01-28T00%3A01%3A08Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Executing","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=ojIT3zvEC43DvcfzETIdy%2FFwQzXREszQEFObgQIqdLo%3D&se=2023-01-28T00%3A01%3A08Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":"2023-01-24T00:01:08.6533255Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1296' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:08 GMT + mise-correlation-id: + - 580fc7a1-c48a-47d2-929d-bb7d743e2560 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=A3ThuTTbxno215AB%2BtQfEyoSBNR27jZpIwWJJdllNH4%3D&se=2023-01-28T00%3A01%3A10Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Executing","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/outputData?sv=2019-07-07&sr=b&sig=bvfmXKugkelgIiXAwfU6WT7sjKgNsaG4meMb4WQ3C7g%3D&se=2023-01-28T00%3A01%3A10Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":"2023-01-24T00:01:08.6533255Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1294' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:10 GMT + mise-correlation-id: + - 9acb306b-e91f-4684-b5b3-cd462d80548e + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=X%2Bl1cJa246nD0qBNUYTFYLuh0K2PdGwW2zi1ZFoRT9U%3D&se=2023-01-28T00%3A01%3A12Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Succeeded","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/rawOutputData?sv=2019-07-07&sr=b&sig=X99ZpReiJbIfvzFaKDDau9lt7b%2BdXrWxVMoUBJ%2FXsoU%3D&se=2023-01-28T00%3A01%3A12Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":"2023-01-24T00:01:08.6533255Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":"2023-01-24T00:01:10.7805788Z","costEstimate":{"currencyCode":"USD","events":[{"dimensionId":"qpu_time_centiseconds","dimensionName":"QPU + Execution Time","measureUnit":"10ms (rounded up)","amountBilled":0.0,"amountConsumed":0.0,"unitPrice":0.0}],"estimatedTotal":0.0},"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1544' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:12 GMT + mise-correlation-id: + - 30e8c501-d201-47dc-ad53-668fc626cf24 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/9299af19-149b-473f-b0c7-caa21f832a04 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/inputData?sv=2019-07-07&sr=b&sig=YpRiai7YWinpgLHPxSs3KdBpH4afnjGSoTKPaOzVEL4%3D&se=2023-01-28T00%3A01%3A13Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.input.json","inputDataFormat":"rigetti.quil.v1","inputParams":{},"metadata":null,"sessionId":null,"status":"Succeeded","jobType":"QuantumComputing","outputDataFormat":"rigetti.quil-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/rawOutputData?sv=2019-07-07&sr=b&sig=TpatYf%2FqKxTbrhPtRXPy91rKNlEkMmRoXRN3nrbOPKE%3D&se=2023-01-28T00%3A01%3A13Z&sp=r&rscd=attachment%3B%20filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json","beginExecutionTime":"2023-01-24T00:01:08.6533255Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"9299af19-149b-473f-b0c7-caa21f832a04","providerId":"rigetti","target":"rigetti.sim.qvm","creationTime":"2023-01-24T00:01:04.0381633+00:00","endExecutionTime":"2023-01-24T00:01:10.7805788Z","costEstimate":{"currencyCode":"USD","events":[{"dimensionId":"qpu_time_centiseconds","dimensionName":"QPU + Execution Time","measureUnit":"10ms (rounded up)","amountBilled":0.0,"amountConsumed":0.0,"unitPrice":0.0}],"estimatedTotal":0.0},"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1540' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:13 GMT + mise-correlation-id: + - e3c89597-f5b1-4cc6-8ce9-e4e891aee5b6 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - keep-alive + User-Agent: + - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.10.6; Windows 10) AZURECLI/2.44.1 + x-ms-date: + - Tue, 24 Jan 2023 00:01:13 GMT + x-ms-range: + - bytes=0-33554431 + x-ms-version: + - '2018-11-09' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-9299af19-149b-473f-b0c7-caa21f832a04/rawOutputData?sv=2019-07-07&sr=b&sig=TpatYf%2FqKxTbrhPtRXPy91rKNlEkMmRoXRN3nrbOPKE%3D&se=2023-01-28T00%3A01%3A13Z&sp=r&rscd=attachment%3B+filename%3Djob-9299af19-149b-473f-b0c7-caa21f832a04.output.json + response: + body: + string: '{"ro":[[1,1]]}' + headers: + accept-ranges: + - bytes + content-disposition: + - attachment; filename=job-9299af19-149b-473f-b0c7-caa21f832a04.output.json + content-length: + - '14' + content-range: + - bytes 0-13/14 + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:13 GMT + etag: + - '"0x8DAFD9E19E3396E"' + last-modified: + - Tue, 24 Jan 2023 00:01:10 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-content-md5: + - IjWSe/NyJii12borFKQGng== + x-ms-blob-type: + - BlockBlob + x-ms-creation-time: + - Tue, 24 Jan 2023 00:01:06 GMT + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-server-encrypted: + - 'true' + x-ms-version: + - '2018-11-09' + status: + code: 206 + message: Partial Content +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/providerStatus + response: + body: + string: '{"value":[{"id":"qci","currentAvailability":"Degraded","targets":[{"id":"qci.simulator","currentAvailability":"Available","averageQueueTime":1,"statusPage":"https://quantumcircuits.com"},{"id":"qci.machine1","currentAvailability":"Unavailable","averageQueueTime":1,"statusPage":"https://quantumcircuits.com"},{"id":"qci.simulator.noisy","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://quantumcircuits.com"}]},{"id":"rigetti","currentAvailability":"Degraded","targets":[{"id":"rigetti.sim.qvm","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-11","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null},{"id":"rigetti.qpu.aspen-m-2","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"},{"id":"rigetti.qpu.aspen-m-3","currentAvailability":"Available","averageQueueTime":5,"statusPage":"https://rigetti.statuspage.io/"}]},{"id":"ionq","currentAvailability":"Available","targets":[{"id":"ionq.qpu","currentAvailability":"Available","averageQueueTime":66466,"statusPage":"https://status.ionq.co"},{"id":"ionq.qpu.aria-1","currentAvailability":"Available","averageQueueTime":1029551,"statusPage":"https://status.ionq.co"},{"id":"ionq.simulator","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://status.ionq.co"}]},{"id":"Microsoft","currentAvailability":"Available","targets":[{"id":"microsoft.paralleltempering-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.paralleltempering.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.simulatedannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.tabu.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.qmc.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.populationannealing-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null},{"id":"microsoft.substochasticmontecarlo-parameterfree.cpu","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"microsoft-qc","currentAvailability":"Available","targets":[{"id":"microsoft.estimator","currentAvailability":"Available","averageQueueTime":0,"statusPage":null}]},{"id":"quantinuum","currentAvailability":"Degraded","targets":[{"id":"quantinuum.hqs-lt-s1","currentAvailability":"Degraded","averageQueueTime":777,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-apival","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-apival","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s1-sim","currentAvailability":"Available","averageQueueTime":1061,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt-s2-sim","currentAvailability":"Available","averageQueueTime":29,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.hqs-lt","currentAvailability":"Degraded","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-1","currentAvailability":"Degraded","averageQueueTime":777,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1sc","currentAvailability":"Available","averageQueueTime":2,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1-2","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2sc","currentAvailability":"Available","averageQueueTime":0,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-1e","currentAvailability":"Available","averageQueueTime":1061,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.sim.h1-2e","currentAvailability":"Available","averageQueueTime":29,"statusPage":"https://www.quantinuum.com/products/h1"},{"id":"quantinuum.qpu.h1","currentAvailability":"Unavailable","averageQueueTime":0,"statusPage":null}]}],"nextLink":null}' + headers: + connection: + - keep-alive + content-length: + - '4971' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:14 GMT + mise-correlation-id: + - 60a63976-917b-488c-860b-6363795d5efc + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + ParameterSetName: + - -t --shots --job-input-format --job-input-file --job-output-format --job-params + -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517?api-version=2022-01-10-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","name":"e2e-test-w9154517","type":"microsoft.quantum/workspaces","location":"eastus","tags":{},"systemData":{"createdBy":"v-wjones@microsoft.com","createdByType":"User","createdAt":"2023-01-23T23:53:56.9639159Z","lastModifiedBy":"v-wjones@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-01-23T23:53:56.9639159Z"},"identity":{"principalId":"75b04db9-f07d-49f2-b05e-c8150e586215","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"providers":[{"providerId":"qci","providerSku":"qci-freepreview","applicationName":"e2e-test-w9154517-qci","provisioningState":"Succeeded"},{"providerId":"rigetti","providerSku":"azure-quantum-credits","applicationName":"e2e-test-w9154517-rigetti","provisioningState":"Succeeded","resourceUsageId":"7964fd5b-f302-4c93-bf64-d458ff733112"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred","applicationName":"e2e-test-w9154517-ionq","provisioningState":"Succeeded","resourceUsageId":"71b0823e-8eab-4e92-a036-28d137c0c498"},{"providerId":"Microsoft","providerSku":"DZH3178M639F","applicationName":"e2e-test-w9154517-Microsoft","provisioningState":"Succeeded"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop","applicationName":"e2e-test-w9154517-microsoft-qc","provisioningState":"Succeeded"},{"providerId":"quantinuum","providerSku":"credits1","applicationName":"e2e-test-w9154517-quantinuum","provisioningState":"Succeeded","resourceUsageId":"be341c87-5098-487f-b767-5a091fa55d3b"}],"provisioningState":"Succeeded","usable":"Yes","storageAccount":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","endpointUri":"https://e2e-test-w9154517.eastus.quantum.azure.com"}}' + headers: + cache-control: + - no-cache + content-length: + - '1906' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:13 GMT + etag: + - '"45004ef6-0000-0100-0000-63cf1f980000"' + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -t --shots --job-input-format --job-input-file --job-output-format --job-params + -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2/listKeys?api-version=2022-09-01&$expand=kerb + response: + body: + string: '{"keys":[{"creationTime":"2021-09-21T22:04:47.1374328Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2021-09-21T22:04:47.1374328Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}' + headers: + cache-control: + - no-cache + content-length: + - '260' + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:14 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-resource-requests: + - '11999' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum run + Connection: + - keep-alive + ParameterSetName: + - -t --shots --job-input-format --job-input-file --job-output-format --job-params + -o + User-Agent: + - AZURECLI/2.44.1 azsdk-python-azure-mgmt-storage/21.0.0 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2?api-version=2022-09-01 + response: + body: + string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","name":"vwjonesstorage2","type":"Microsoft.Storage/storageAccounts","location":"eastus","tags":{},"properties":{"keyCreationTime":{"key1":"2021-09-21T22:04:47.1374328Z","key2":"2021-09-21T22:04:47.1374328Z"},"privateEndpointConnections":[],"minimumTlsVersion":"TLS1_0","allowBlobPublicAccess":true,"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-09-21T22:04:47.1374328Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-09-21T22:04:47.0124593Z","primaryEndpoints":{"blob":"https://vwjonesstorage2.blob.core.windows.net/","queue":"https://vwjonesstorage2.queue.core.windows.net/","table":"https://vwjonesstorage2.table.core.windows.net/","file":"https://vwjonesstorage2.file.core.windows.net/"},"primaryLocation":"eastus","statusOfPrimary":"available"}}' + headers: + cache-control: + - no-cache + content-length: + - '1277' + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:14 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:15 GMT + x-ms-version: + - '2021-08-06' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14?restype=container + response: + body: + string: "\uFEFFContainerNotFoundThe + specified container does not exist.\nRequestId:3105c290-801e-0042-7a86-2ffb8d000000\nTime:2023-01-24T00:01:15.4120367Z" + headers: + content-length: + - '223' + content-type: + - application/xml + date: + - Tue, 24 Jan 2023 00:01:15 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-error-code: + - ContainerNotFound + x-ms-version: + - '2021-08-06' + status: + code: 404 + message: The specified container does not exist. +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:15 GMT + x-ms-version: + - '2021-08-06' + method: PUT + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14?restype=container + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Tue, 24 Jan 2023 00:01:15 GMT + etag: + - '"0x8DAFD9E1CC094C8"' + last-modified: + - Tue, 24 Jan 2023 00:01:15 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-version: + - '2021-08-06' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-date: + - Tue, 24 Jan 2023 00:01:15 GMT + x-ms-version: + - '2021-08-06' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14?restype=container + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Tue, 24 Jan 2023 00:01:15 GMT + etag: + - '"0x8DAFD9E1CC094C8"' + last-modified: + - Tue, 24 Jan 2023 00:01:15 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-default-encryption-scope: + - $account-encryption-key + x-ms-deny-encryption-scope-override: + - 'false' + x-ms-has-immutability-policy: + - 'false' + x-ms-has-legal-hold: + - 'false' + x-ms-immutable-storage-with-versioning-enabled: + - 'false' + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-version: + - '2021-08-06' + status: + code: 200 + message: OK +- request: + body: '{"gateset": "qis", "qubits": 3, "circuit": [{"gate": "h", "targets": [0]}, + {"gate": "x", "targets": [1], "controls": [0]}, {"gate": "x", "targets": [2], + "controls": [1]}]}' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '171' + Content-Type: + - application/octet-stream + If-None-Match: + - '*' + User-Agent: + - azsdk-python-storage-blob/12.14.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + x-ms-blob-content-type: + - application/json + x-ms-blob-type: + - BlockBlob + x-ms-date: + - Tue, 24 Jan 2023 00:01:15 GMT + x-ms-version: + - '2021-08-06' + method: PUT + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - 3+pg2wKa9x2rK+IB+BmzGA== + date: + - Tue, 24 Jan 2023 00:01:15 GMT + etag: + - '"0x8DAFD9E1CEC5F82"' + last-modified: + - Tue, 24 Jan 2023 00:01:15 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-content-crc64: + - VPUiKdL2pXs= + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2021-08-06' + status: + code: 201 + message: Created +- request: + body: '{"containerUri": "https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14", + "inputDataFormat": "ionq.circuit.v1", "inputParams": {"count": 100, "shots": + 100}, "providerId": "ionq", "target": "ionq.simulator", "outputDataFormat": + "ionq.quantum-results.v1", "tags": []}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '306' + Content-Type: + - application/json + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: PUT + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net:443/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"Unknown","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net:443/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":null,"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '900' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:16 GMT + mise-correlation-id: + - a68dc305-e07e-400b-9f55-202048a5eea4 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=mkUU29DndFtCn%2FuDSiWzhFiivQgWQlKRlohzU3ATyx0%3D&se=2023-01-28T00%3A01%3A16Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=4S7kWpmHEJtgLqdWGEAL2NfX9i%2BuN%2FOU8Wxyi95Vdcg%3D&se=2023-01-28T00%3A01%3A16Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1289' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:16 GMT + mise-correlation-id: + - 63ef75df-7dc7-46a1-ae10-7bf780156d38 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=mkUU29DndFtCn%2FuDSiWzhFiivQgWQlKRlohzU3ATyx0%3D&se=2023-01-28T00%3A01%3A16Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=4S7kWpmHEJtgLqdWGEAL2NfX9i%2BuN%2FOU8Wxyi95Vdcg%3D&se=2023-01-28T00%3A01%3A16Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1289' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:16 GMT + mise-correlation-id: + - eab616d5-a8a1-42ed-8904-52c5369dfd06 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=TST8VFMgakopwOYokKH%2BG%2FKE0rOK9oNuSk%2FQIVcAm1g%3D&se=2023-01-28T00%3A01%3A17Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=OIULmt%2BruIUV2rd8srnAZFM4NGxtBRSEm0S6nMXZtVA%3D&se=2023-01-28T00%3A01%3A17Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1291' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:17 GMT + mise-correlation-id: + - a90771df-eab6-4c75-96ad-dca396aa8aaa + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=TST8VFMgakopwOYokKH%2BG%2FKE0rOK9oNuSk%2FQIVcAm1g%3D&se=2023-01-28T00%3A01%3A17Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=OIULmt%2BruIUV2rd8srnAZFM4NGxtBRSEm0S6nMXZtVA%3D&se=2023-01-28T00%3A01%3A17Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1291' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:17 GMT + mise-correlation-id: + - 95916ed4-641d-4e6d-ac59-e6e0a8bdb78b + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=9uFU6Oa%2BrlbtuGySZXsijXz13wPAXzfKnZqGBSMXye4%3D&se=2023-01-28T00%3A01%3A18Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=dwDghUIXtHNI%2BIgr%2FMv%2BTg5%2FWOUMjNXHjMJIzqlt3z4%3D&se=2023-01-28T00%3A01%3A18Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1293' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:18 GMT + mise-correlation-id: + - 975d87fc-d555-4083-b24f-955ab26ca6fc + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=ry6z01ZBqwAaKFjkuCdNc1Hv92sOxmgeHjBbfKvMVvw%3D&se=2023-01-28T00%3A01%3A19Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=cuH2n1llb02s9QcQMq9%2BTDLzptTAAQU%2BS87CQQfGjYg%3D&se=2023-01-28T00%3A01%3A19Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1287' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:19 GMT + mise-correlation-id: + - 42a29ad2-6148-44ca-ac9c-eccefc31709a + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=jmZzKlOZPmz60Enp3BfJhiCfvaIxQn0Twd2%2BpvJpPBQ%3D&se=2023-01-28T00%3A01%3A21Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Waiting","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/outputData?sv=2019-07-07&sr=b&sig=wgLX5vQRFNSwSbKWTL2v6R8S4NznBOa%2F2h2J%2BE6JH0g%3D&se=2023-01-28T00%3A01%3A21Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":null,"cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":null,"costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1289' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:21 GMT + mise-correlation-id: + - 06239b25-6f12-4658-abb5-46d005768d89 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=qHVjRfOSy6dNin%2BynpbFp40lm3m5F8M9HSCn%2FYBSEa4%3D&se=2023-01-28T00%3A01%3A23Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Succeeded","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/rawOutputData?sv=2019-07-07&sr=b&sig=bsjokMHDEus8m7q1qUIzbgP%2BTLq3aSXw4bbUZqnbDv4%3D&se=2023-01-28T00%3A01%3A23Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":"2023-01-24T00:01:22.232Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":"2023-01-24T00:01:22.313Z","costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1338' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:23 GMT + mise-correlation-id: + - ff85161a-2f4c-4e6a-8119-a6f8b5c6d71f + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - az-cli-ext/0.17.0.1 azsdk-python-quantum/0.0.0.1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + method: GET + uri: https://eastus.quantum.azure.com/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517/jobs/398f62ca-1311-458f-8843-d78c0ebf7a14 + response: + body: + string: '{"containerUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14","inputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/inputData?sv=2019-07-07&sr=b&sig=qHVjRfOSy6dNin%2BynpbFp40lm3m5F8M9HSCn%2FYBSEa4%3D&se=2023-01-28T00%3A01%3A23Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.input.json","inputDataFormat":"ionq.circuit.v1","inputParams":{"count":100,"shots":100},"metadata":null,"sessionId":null,"status":"Succeeded","jobType":"QuantumComputing","outputDataFormat":"ionq.quantum-results.v1","outputDataUri":"https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/rawOutputData?sv=2019-07-07&sr=b&sig=bsjokMHDEus8m7q1qUIzbgP%2BTLq3aSXw4bbUZqnbDv4%3D&se=2023-01-28T00%3A01%3A23Z&sp=r&rscd=attachment%3B%20filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json","beginExecutionTime":"2023-01-24T00:01:22.232Z","cancellationTime":null,"quantumComputingData":{"count":1},"errorData":null,"isCancelling":false,"tags":[],"name":null,"id":"398f62ca-1311-458f-8843-d78c0ebf7a14","providerId":"ionq","target":"ionq.simulator","creationTime":"2023-01-24T00:01:16.1680299+00:00","endExecutionTime":"2023-01-24T00:01:22.313Z","costEstimate":null,"itemType":"Job"}' + headers: + connection: + - keep-alive + content-length: + - '1338' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:23 GMT + mise-correlation-id: + - 83c80300-3ad4-48a3-be0a-ec6d6413c799 + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + server: + - Microsoft-IIS/10.0 + set-cookie: + - ApplicationGatewayAffinityCORS=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/; SameSite=None; + Secure + - ApplicationGatewayAffinity=f41f4d84e6de1cfe7357bf648ccde6bc; Path=/ + - ARRAffinity=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + - ARRAffinitySameSite=9d716053ef092553e7bdd2639d89f002241b80715630c2dbb839c205a5e8d5f8;Path=/;HttpOnly;SameSite=None;Secure;Domain=app-jobscheduler-westus-003.ase-jobscheduler-westus-003.appserviceenvironment.net + strict-transport-security: + - max-age=2592000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - keep-alive + User-Agent: + - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.10.6; Windows 10) AZURECLI/2.44.1 + x-ms-date: + - Tue, 24 Jan 2023 00:01:23 GMT + x-ms-range: + - bytes=0-33554431 + x-ms-version: + - '2018-11-09' + method: GET + uri: https://vwjonesstorage2.blob.core.windows.net/quantum-job-398f62ca-1311-458f-8843-d78c0ebf7a14/rawOutputData?sv=2019-07-07&sr=b&sig=bsjokMHDEus8m7q1qUIzbgP%2BTLq3aSXw4bbUZqnbDv4%3D&se=2023-01-28T00%3A01%3A23Z&sp=r&rscd=attachment%3B+filename%3Djob-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json + response: + body: + string: '{"histogram":{"0":0.500000000,"7":0.500000000}}' + headers: + accept-ranges: + - bytes + content-disposition: + - attachment; filename=job-398f62ca-1311-458f-8843-d78c0ebf7a14.output.json + content-length: + - '47' + content-range: + - bytes 0-46/47 + content-type: + - application/json + date: + - Tue, 24 Jan 2023 00:01:23 GMT + etag: + - '"0x8DAFD9E21079149"' + last-modified: + - Tue, 24 Jan 2023 00:01:22 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-type: + - BlockBlob + x-ms-creation-time: + - Tue, 24 Jan 2023 00:01:18 GMT + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-server-encrypted: + - 'true' + x-ms-version: + - '2018-11-09' + status: + code: 206 + message: Partial Content +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -g -w + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517?api-version=2022-01-10-preview + response: + body: + string: 'null' + headers: + azure-asyncoperation: + - https://management.azure.com/providers/Microsoft.Quantum/locations/EASTUS/operationStatuses/8e852d6e-256c-4085-8b18-f975964d129a*9791A27D973CEDA5971DD16C3BE876DA873258CAC7236125D24D1E999120C663?api-version=2022-01-10-preview + cache-control: + - no-cache + content-length: + - '4' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:25 GMT + etag: + - '"45004ff6-0000-0100-0000-63cf1fd50000"' + expires: + - '-1' + location: + - https://management.azure.com/providers/Microsoft.Quantum/locations/EASTUS/operationStatuses/8e852d6e-256c-4085-8b18-f975964d129a*9791A27D973CEDA5971DD16C3BE876DA873258CAC7236125D24D1E999120C663?api-version=2022-01-10-preview + mise-correlation-id: + - 673c2de1-842d-4250-a0b1-d5a3135af34f + pragma: + - no-cache + request-context: + - appId=cid-v1:4d6ac272-7369-45c6-9036-63d733c8519f + set-cookie: + - ARRAffinity=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ARRAffinitySameSite=8ff86c9a27601d7f5b6518ec4d18af424875e57b5b1d58a058e5ff9db2bf1a1f;Path=/;HttpOnly;SameSite=None;Secure;Domain=rpcontrol-eastus.azurewebsites.net + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + path=/; secure + - ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + samesite=none; path=/; secure + strict-transport-security: + - max-age=31536000; includeSubDomains + x-azure-ref: + - 01R/PYwAAAACpX24CzKoETZt8uW5nGJVhTU5aMjIxMDYwNjExMDM1AGU0ODIyNTNiLTllMDUtNDA1ZS1hODNmLTU4NmVlMWQ1NTNlNA== + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + x-ms-ratelimit-remaining-subscription-deletes: + - '14999' + x-powered-by: + - ASP.NET + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - quantum workspace delete + Connection: + - keep-alive + Cookie: + - ASLBSA=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548; + ASLBSACORS=0003d40efdced3b125786ca8cb22325eb49a925b534478081c4d828d5b638143f548 + ParameterSetName: + - -g -w + User-Agent: + - AZURECLI/2.44.1 azsdk-python-mgmt-quantum/1.0.0b1 Python/3.10.6 (Windows-10-10.0.22621-SP0) + az-cli-ext/0.17.0.1 + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517?api-version=2022-01-10-preview + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Quantum/workspaces/e2e-test-w9154517","name":"e2e-test-w9154517","type":"microsoft.quantum/workspaces","location":"eastus","tags":{},"systemData":{"createdBy":"v-wjones@microsoft.com","createdByType":"User","createdAt":"2023-01-23T23:53:56.9639159Z","lastModifiedBy":"v-wjones@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-01-23T23:53:56.9639159Z"},"identity":{"principalId":"75b04db9-f07d-49f2-b05e-c8150e586215","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"providers":[{"providerId":"qci","providerSku":"qci-freepreview","applicationName":"e2e-test-w9154517-qci","provisioningState":"Succeeded"},{"providerId":"rigetti","providerSku":"azure-quantum-credits","applicationName":"e2e-test-w9154517-rigetti","provisioningState":"Succeeded","resourceUsageId":"7964fd5b-f302-4c93-bf64-d458ff733112"},{"providerId":"ionq","providerSku":"pay-as-you-go-cred","applicationName":"e2e-test-w9154517-ionq","provisioningState":"Succeeded","resourceUsageId":"71b0823e-8eab-4e92-a036-28d137c0c498"},{"providerId":"Microsoft","providerSku":"DZH3178M639F","applicationName":"e2e-test-w9154517-Microsoft","provisioningState":"Succeeded"},{"providerId":"microsoft-qc","providerSku":"learn-and-develop","applicationName":"e2e-test-w9154517-microsoft-qc","provisioningState":"Succeeded"},{"providerId":"quantinuum","providerSku":"credits1","applicationName":"e2e-test-w9154517-quantinuum","provisioningState":"Succeeded","resourceUsageId":"be341c87-5098-487f-b767-5a091fa55d3b"}],"provisioningState":"Deleting","usable":"Yes","storageAccount":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-v-wjones2/providers/Microsoft.Storage/storageAccounts/vwjonesstorage2","endpointUri":"https://e2e-test-w9154517.eastus.quantum.azure.com"}}' + headers: + cache-control: + - no-cache + content-length: + - '1905' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 24 Jan 2023 00:01:25 GMT + etag: + - '"45004ff6-0000-0100-0000-63cf1fd50000"' + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-ms-providerhub-traffic: + - 'True' + status: + code: 200 + message: OK +version: 1 diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py index 3e448ef96bb..2c1aa9c936f 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_jobs.py @@ -244,58 +244,47 @@ def test_convert_numeric_params(self): _convert_numeric_params(test_job_params) assert test_job_params == {"integer1": 1, "float1.5": 1.5, "integer2": 2, "float2.5": 2.5, "integer3": 3, "float3.5": 3.5} - # Show that it doesn't modify non-numeric strings + # Make sure it doesn't modify non-numeric strings test_job_params = {"string1": "string_value1", "string2": "string_value2", "string3": "string_value3"} _convert_numeric_params(test_job_params) assert test_job_params == {"string1": "string_value1", "string2": "string_value2", "string3": "string_value3"} - # >>>>>>>> Add a test that has tags and metadata + # Make sure it doesn't modify the "tags" list + test_job_params = {"string1": "string_value1", "tags": ["tag1", "tag2", "3", "4"], "integer1": "1"} + _convert_numeric_params(test_job_params) + assert test_job_params == {"string1": "string_value1", "tags": ["tag1", "tag2", "3", "4"], "integer1": 1} + + # Make sure it doesn't modify nested dict like metadata uses + test_job_params = {"string1": "string_value1", "metadata": {"meta1": "meta_value1", "meta2": "2"}, "integer1": "1"} + _convert_numeric_params(test_job_params) + assert test_job_params == {"string1": "string_value1", "metadata": {"meta1": "meta_value1", "meta2": "2"}, "integer1": 1} @live_only() - def test_submit_qir(self): + def test_submit(self): test_location = get_test_workspace_location() test_resource_group = get_test_resource_group() - # test_workspace_temp = get_test_workspace_random_name() - test_workspace_temp = "e2e-test-v-wjones-local" # <<<<< Temporarily used for local debugging <<<<< - # test_qir-provider_sku_list = "qci/qci-freepreview" - test_qir_provider_sku_list = "qci/qci-freepreview, Microsoft/DZH3178M639F" # <<<<< Microsoft SKU added here because it's also an auto-add provider, speeds up workspace creation <<<<< - # <<<<< # <<<<< Remove Microsoft SKU after Task 46910 is implemented <<<<< - test_storage_account = get_test_workspace_storage() - test_bitcode_pathname = "src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc" - - # # Create a workspace - # self.cmd(f'az quantum workspace create -g {test_resource_group} -w {test_workspace_temp} -l {test_location} -a {test_storage_account} -r "{test_qir_provider_sku_list}" -o json', checks=[ - # self.check("name", DEPLOYMENT_NAME_PREFIX + test_workspace_temp), - # ]) - # <<<<< Temporarily commented-out to speed up the local tests during debugging <<<<< - - # Run a QIR job + test_workspace_temp = get_test_workspace_random_name() + test_provider_sku_list = "qci/qci-freepreview,rigetti/azure-quantum-credits,ionq/pay-as-you-go-cred,Microsoft/DZH3178M639F" + test_storage = get_test_workspace_storage() + + self.cmd(f"az quantum workspace create -g {test_resource_group} -w {test_workspace_temp} -l {test_location} -a {test_storage} -r {test_provider_sku_list}") self.cmd(f"az quantum workspace set -g {test_resource_group} -w {test_workspace_temp} -l {test_location}") - self.cmd("az quantum target set -t qci.simulator") - # results = self.cmd("az quantum run --shots 100 --job-input-format qir.v1 --job-input-file src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator -o json") + # Run a Quil pass-through job on Rigetti + results = self.cmd("az quantum run -t rigetti.sim.qvm --job-input-format rigetti.quil.v1 -t rigetti.sim.qvm --job-input-file src/quantum/azext_quantum/tests/latest/input_data/bell-state.quil --job-output-format rigetti.quil-results.v1 -o json").get_output_in_json() + self.assertIn("ro", results) + + # Run a Qiskit pass-through job on IonQ + results = self.cmd("az quantum run -t ionq.simulator --shots 100 --job-input-format ionq.circuit.v1 --job-input-file src/quantum/azext_quantum/tests/latest/input_data/Qiskit-3-qubit-GHZ-circuit.json --job-output-format ionq.quantum-results.v1 --job-params count=100 content-type=application/json -o json").get_output_in_json() + self.assertIn("histogram", results) + + # Unexplained behavior: upload_blob fails with on the next two tests, but the same commands succeed when run interactively. + # # Run a QIR job on QCI + # results = self.cmd("az quantum run -t qci.simulator --shots 100 --job-input-format qir.v1 --job-input-file src/quantum/azext_quantum/tests/latest/input_data/Qrng.bc --entry-point Qrng__SampleQuantumRandomNumberGenerator -o json") # self.assertIn("Histogram", results) + # + # # Run a QIO job + # results = self.cmd("az quantum run -t microsoft.paralleltempering-parameterfree.cpu --job-input-format microsoft.qio.v2 --job-input-file src/quantum/azext_quantum/tests/latest/input_data/QIO-Problem-2.json -o json").get_output_in_json() + # self.assertIn("solutions", results) - # self.cmd(f"az quantum run --shots 99 --job-input-format qir.v1 --job-input-file {test_bitcode_pathname} --entry-point Qrng__SampleQuantumRandomNumberGenerator") - - # >>>>> Trying to suppress logging because "azdev test" tries to log the bitcode file data as utf-8 unicode and crashes >>>> - import logging - # logger = logging.getLogger(__name__) - logger = logging.getLogger() - - # logger.disable() - # logger.disabled() - # logger.shutdown() - # logger.manager.disable() - # logger.setLevel(logging.CRITICAL + 1) - # logger.disabled == True - logger.addFilter(lambda record: False) - - #results = self.cmd(f"az quantum run --shots 99 --job-input-format qir.v1 --job-input-file {test_bitcode_pathname} --entry-point Qrng__SampleQuantumRandomNumberGenerator").get_output_in_json() - - # # Delete the workspace - # self.cmd(f'az quantum workspace delete -g {test_resource_group} -w {test_workspace_temp} -o json', checks=[ - # self.check("name", test_workspace_temp), - # self.check("provisioningState", "Deleting") - # ]) - # <<<<< Temporarily commented-out during local debugging: Re-use the workspace for local tests <<<<< + self.cmd(f'az quantum workspace delete -g {test_resource_group} -w {test_workspace_temp}') diff --git a/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py b/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py index 02b1754aa85..dc0c8e5836c 100644 --- a/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py +++ b/src/quantum/azext_quantum/tests/latest/test_quantum_targets.py @@ -10,7 +10,9 @@ from azure.cli.testsdk.scenario_tests import AllowLargeResponse, live_only from azure.cli.testsdk import (ScenarioTest, ResourceGroupPreparer) -from .utils import get_test_resource_group, get_test_workspace, get_test_workspace_location, issue_cmd_with_param_missing +from .utils import (get_test_resource_group, get_test_workspace, get_test_workspace_location, issue_cmd_with_param_missing, + get_test_workspace_random_name, get_test_workspace_storage, get_test_target_provider_sku_list, + get_test_target_provider, get_test_target_target) from ...operations.target import get_provider, TargetInfo TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..')) @@ -56,11 +58,22 @@ def test_target_errors(self): @live_only() def test_get_provider(self): - test_location = get_test_workspace_location() - test_workspace = get_test_workspace() test_resource_group = get_test_resource_group() - # test_target = get_test_target()) - # test_provider = get_test_provider - # returned_provider = get_provider(self.cmd, test_target, test_resource_group, test_workspace, test_location) - # assert returned_provider == test_provider - # >>>>> TODO: Finish this test + test_location = get_test_workspace_location() + test_storage = get_test_workspace_storage() + test_target_provider_sku_list = get_test_target_provider_sku_list() + test_workspace_temp = get_test_workspace_random_name() + + self.cmd(f'az quantum workspace create -g {test_resource_group} -w {test_workspace_temp} -l {test_location} -a {test_storage} -r "{test_target_provider_sku_list}"') + + test_target = get_test_target_target() + test_expected_provider = get_test_target_provider() + test_returned_provider = get_provider(self, test_target, test_resource_group, test_workspace_temp, test_location) + assert test_returned_provider == test_expected_provider + + test_target = "nonexistant.target" + test_expected_provider = None + test_returned_provider = get_provider(self, test_target, test_resource_group, test_workspace_temp, test_location) + assert test_returned_provider == test_expected_provider + + self.cmd(f'az quantum workspace delete -g {test_resource_group} -w {test_workspace_temp}') diff --git a/src/quantum/azext_quantum/tests/latest/utils.py b/src/quantum/azext_quantum/tests/latest/utils.py index a2540136728..7f6f37d8ab3 100644 --- a/src/quantum/azext_quantum/tests/latest/utils.py +++ b/src/quantum/azext_quantum/tests/latest/utils.py @@ -10,7 +10,11 @@ TEST_WORKSPACE_DEFAULT_STORAGE = "e2etests" TEST_WORKSPACE_DEFAULT_STORAGE_GRS = "e2etestsgrs" TEST_WORKSPACE_DEFAULT_PROVIDER_SKU_LIST = "Microsoft/Basic" -TEST_CAPABILITIES_DEFAULT = "new.microsoft;submit.microsoft" +TEST_CAPABILITIES_DEFAULT = "new.microsoft;submit.microsoft" + +TEST_TARGET_DEFAULT_PROVIDER_SKU_LIST = "microsoft-qc/learn-and-develop" +TEST_TARGET_DEFAULT_PROVIDER = "microsoft-qc" +TEST_TARGET_DEFAULT_TARGET = "microsoft.estimator" def get_from_os_environment(env_name, default): import os @@ -40,6 +44,15 @@ def get_test_workspace_provider_sku_list(): def get_test_capabilities(): return get_from_os_environment("AZURE_QUANTUM_CAPABILITIES", TEST_CAPABILITIES_DEFAULT).lower() +def get_test_target_provider_sku_list(): + return get_from_os_environment("AZURE_QUANTUM_TARGET_PROVIDER_SKU_LIST", TEST_TARGET_DEFAULT_PROVIDER_SKU_LIST) + +def get_test_target_provider(): + return get_from_os_environment("AZURE_QUANTUM_PROVIDER", TEST_TARGET_DEFAULT_PROVIDER) + +def get_test_target_target(): + return get_from_os_environment("AZURE_QUANTUM_TARGET", TEST_TARGET_DEFAULT_TARGET) + def get_test_workspace_random_name(): import random return "e2e-test-w" + str(random.randint(1000000, 9999999)) From 1285161f7b4bf064ecf152650b0fca207ece45f2 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 23 Jan 2023 18:05:34 -0800 Subject: [PATCH 52/65] Supply correct default content-type for Rigetti QIR --- src/quantum/azext_quantum/operations/job.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index bc0b236575b..f2ac7617c66 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -332,7 +332,11 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: if job_type == QIR_JOB: if content_type is None: - content_type = "application/x-qir.v1" # <<<<< Is this a valid default for all QIR jobs? + if provider_id.lower() == "rigetti": + content_type = "application/octet-stream" + else: + # MAINTENANCE NOTE: The following value is valid for QCI and Quantinuum. Make sure it's correct to new providers. + content_type = "application/x-qir.v1" content_encoding = None with open(job_input_file, "rb") as input_file: From c49c307f33dc4ca7cf103da02a1d3289075aa56c Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 23 Jan 2023 21:05:27 -0800 Subject: [PATCH 53/65] Correct typo in comment --- src/quantum/azext_quantum/operations/job.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index f2ac7617c66..6285bd9607c 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -335,7 +335,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if provider_id.lower() == "rigetti": content_type = "application/octet-stream" else: - # MAINTENANCE NOTE: The following value is valid for QCI and Quantinuum. Make sure it's correct to new providers. + # MAINTENANCE NOTE: The following value is valid for QCI and Quantinuum. + # Make sure it's correct for new providers when they are added. If not, + # modify this logic. content_type = "application/x-qir.v1" content_encoding = None From b0c52624a9bd0977ecbde94dd3b25ed8b9aaf9ca Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Mon, 23 Jan 2023 21:09:57 -0800 Subject: [PATCH 54/65] Delete commented-out import statements --- src/quantum/azext_quantum/operations/job.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 6285bd9607c..15b54a2d043 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -494,8 +494,6 @@ def output(cmd, job_id, resource_group_name, workspace_name, location): Get the results of running a Q# job. """ import tempfile - # import json - # import os from azure.cli.command_modules.storage._client_factory import blob_data_service_factory path = os.path.join(tempfile.gettempdir(), job_id) From 9f054dcc1e252ecae963cdb046f09ab584ec2a58 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 24 Jan 2023 10:00:24 -0800 Subject: [PATCH 55/65] Require --job-input-format when --job-input-file is specified --- src/quantum/azext_quantum/operations/job.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 15b54a2d043..f1ab3b6f914 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -29,7 +29,7 @@ DEFAULT_SHOTS = 500 QIO_DEFAULT_TIMEOUT = 100 -ERROR_MSG_MISSING_INPUT_FILE = "The following argument is required: --job-input-file" # NOTE: The Azure CLI core generates a similar error message, but "the" is lowercase and "arguments" is always plural. +ERROR_MSG_MISSING_INPUT_FORMAT = "The following argument is required: --job-input-format" # NOTE: The Azure CLI core generates a similar error message, but "the" is lowercase and "arguments" is always plural. ERROR_MSG_MISSING_OUTPUT_FORMAT = "The following argument is required: --job-output-format" JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" @@ -213,7 +213,7 @@ def submit(cmd, program_args, resource_group_name, workspace_name, location, tar """ Submit a quantum program to run on Azure Quantum. """ - if job_input_format is None: + if job_input_file is None: return _submit_qsharp(cmd, program_args, resource_group_name, workspace_name, location, target_id, project, job_name, shots, storage, no_build, job_params, target_capability) @@ -228,6 +228,8 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati """ Submit QIR bitcode, QIO problem JSON, or a pass-through job to run on Azure Quantum. """ + if job_input_format is None: + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) # Get workspace, target, and provider information ws_info = WorkspaceInfo(cmd, resource_group_name, workspace_name, location) @@ -258,9 +260,6 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) - if job_input_file is None: - raise RequiredArgumentMissingError(ERROR_MSG_MISSING_INPUT_FILE, JOB_SUBMIT_DOC_LINK_MSG) - # Extract "metadata" and "tags" from job_params, then remove those parameters from job_params, # since they should not be included in the "inputParams" parameter of job_details. They are # separate parameters of job_details. From 9686b89c130f3a2c7269bd51bd59090970509ed1 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 24 Jan 2023 13:51:36 -0800 Subject: [PATCH 56/65] Add more error handling code --- src/quantum/azext_quantum/operations/job.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index f1ab3b6f914..0b921abb356 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -316,8 +316,11 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati content_type = "application/json" if content_encoding is None: content_encoding = "gzip" - with open(job_input_file, encoding="utf-8") as qio_file: - uncompressed_blob_data = qio_file.read() + try: + with open(job_input_file, encoding="utf-8") as qio_file: + uncompressed_blob_data = qio_file.read() + except (IOError, OSError) as e: + raise FileOperationError(f"An error occurred opening the input file: {job_input_file}") from e if ("content_type" in uncompressed_blob_data and "application/x-protobuf" in uncompressed_blob_data) or (content_type.lower() == "application/x-protobuf"): raise InvalidArgumentValueError('Content type "application/x-protobuf" is not supported.') @@ -339,14 +342,18 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati # modify this logic. content_type = "application/x-qir.v1" content_encoding = None - - with open(job_input_file, "rb") as input_file: - blob_data = input_file.read() + try: + with open(job_input_file, "rb") as input_file: + blob_data = input_file.read() + except (IOError, OSError) as e: + raise FileOperationError(f"An error occurred opening the input file: {job_input_file}") from e # Upload the input file to the workspace's storage account if storage is None: from .workspace import get as ws_get ws = ws_get(cmd) + if ws.storage_account is None: + raise RequiredArgumentMissingError("No storage account specified or linked with workspace.") storage = ws.storage_account.split('/')[-1] job_id = str(uuid.uuid4()) container_name = "quantum-job-" + job_id From 8357ae031ea6351c1aa893c8d84baa836d5e0f07 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 25 Jan 2023 16:10:19 -0800 Subject: [PATCH 57/65] Add fix for Bug 50331 --- src/quantum/azext_quantum/operations/workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quantum/azext_quantum/operations/workspace.py b/src/quantum/azext_quantum/operations/workspace.py index b2db7bc8fed..38e6d8dcd1a 100644 --- a/src/quantum/azext_quantum/operations/workspace.py +++ b/src/quantum/azext_quantum/operations/workspace.py @@ -118,7 +118,7 @@ def _autoadd_providers(cmd, providers_in_region, providers_selected, workspace_l # Don't duplicate a provider/sku if it was also specified in the command's -r parameter provider_already_added = False for already_selected_provider in providers_selected: - if already_selected_provider['provider_id'] == provider.id and already_selected_provider['sku'] == sku.id: + if already_selected_provider['provider_id'] == provider.id: provider_already_added = True break if not provider_already_added: From a8be909fad2038cf8180c1959b4bf7429c1adc7a Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Wed, 25 Jan 2023 16:14:00 -0800 Subject: [PATCH 58/65] Increment build number for bug bash wheel --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index a0e28e8efe7..61bbe5ac26f 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.17.0.1" +CLI_REPORTED_VERSION = "0.17.0.2" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 7136ee2d199..96236240384 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.17.0.1' +VERSION = '0.17.0.2' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From 9ab58ca1e9e8159fe357e980370d58b3f322cd8e Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 26 Jan 2023 18:02:54 -0800 Subject: [PATCH 59/65] Make --entry-point required on QIR jobs --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/azext_quantum/operations/job.py | 10 +++++++++- src/quantum/setup.py | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index 61bbe5ac26f..8bacf10f915 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.17.0.2" +CLI_REPORTED_VERSION = "0.17.0.3" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 0b921abb356..617239c29da 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -31,6 +31,7 @@ ERROR_MSG_MISSING_INPUT_FORMAT = "The following argument is required: --job-input-format" # NOTE: The Azure CLI core generates a similar error message, but "the" is lowercase and "arguments" is always plural. ERROR_MSG_MISSING_OUTPUT_FORMAT = "The following argument is required: --job-output-format" +ERROR_MSG_MISSING_ENTRY_POINT = "The following argument is required on QIR jobs: --entry-point" JOB_SUBMIT_DOC_LINK_MSG = "See https://learn.microsoft.com/cli/azure/quantum/job?view=azure-cli-latest#az-quantum-job-submit" # Job types @@ -260,6 +261,10 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati else: raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) + # An entry point is required on QIR jobs + if job_type == QIR_JOB and entry_point is None and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) + # Extract "metadata" and "tags" from job_params, then remove those parameters from job_params, # since they should not be included in the "inputParams" parameter of job_details. They are # separate parameters of job_details. @@ -390,6 +395,9 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati job_params["targetCapability"] = target_capability if entry_point is not None: job_params["entryPoint"] = entry_point + # # An entry point is required on QIR jobs + # elif job_type == QIR_JOB and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): + # raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) # Convert "count" to an integer if "count" in job_params.keys(): @@ -406,7 +414,7 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati if "arguments" not in job_params: job_params["arguments"] = [] - # ...and supply a default "shots" if it's not specified (like Q# does) + # ...supply a default "shots" if it's not specified (like Q# does) if "shots" not in job_params: job_params["shots"] = DEFAULT_SHOTS diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 96236240384..a787b4c376a 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.17.0.2' +VERSION = '0.17.0.3' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From 417e641a5b88e2f87bf788ab94c2c6e4f489b254 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Thu, 26 Jan 2023 18:04:29 -0800 Subject: [PATCH 60/65] Delete commented-out code --- src/quantum/azext_quantum/operations/job.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 617239c29da..576f5574263 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -395,9 +395,6 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati job_params["targetCapability"] = target_capability if entry_point is not None: job_params["entryPoint"] = entry_point - # # An entry point is required on QIR jobs - # elif job_type == QIR_JOB and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): - # raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) # Convert "count" to an integer if "count" in job_params.keys(): From 1bbf8231eb1a8eaea0c99bd1ca617e3e56c10a85 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 27 Jan 2023 13:08:27 -0800 Subject: [PATCH 61/65] Extend entry-point param validation to allow entryPoint in 'items' list --- src/quantum/azext_quantum/operations/job.py | 23 +++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 576f5574263..e3f50592caa 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -262,8 +262,27 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) # An entry point is required on QIR jobs - if job_type == QIR_JOB and entry_point is None and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): - raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) + # if job_type == QIR_JOB and entry_point is None and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): + # raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) + if job_type == QIR_JOB: + # An entry point is required for a QIR job, but there are four ways to specify it: + # - Use the --entry-point parameter + # - Include it in --job-params as entryPoint=MyEntryPoint + # - Include it as 'entryPoint':'MyEntryPoint' in a JSON --job-params string or file + # - Include it in an "items" list in a JSON --job-params string or file + found_entry_point_in_items = False + if "items" in job_params: + items_list = job_params["items"] + if isinstance(items_list, type([])): # "list" has been redefined as a function name + for item in items_list: + if isinstance(item, dict): + for item_dict in items_list: + if "entryPoint" in item_dict: + if item_dict["entryPoint"] is not None: + found_entry_point_in_items = True + if not found_entry_point_in_items: + if entry_point is None and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): + raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) # Extract "metadata" and "tags" from job_params, then remove those parameters from job_params, # since they should not be included in the "inputParams" parameter of job_details. They are From 22952f40cbbda63c7a583f37f861f799e1b65480 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 27 Jan 2023 13:25:24 -0800 Subject: [PATCH 62/65] Delete commented-out code --- src/quantum/azext_quantum/operations/job.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index e3f50592caa..4eb5f6d7dd6 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -262,10 +262,8 @@ def _submit_directly_to_service(cmd, resource_group_name, workspace_name, locati raise RequiredArgumentMissingError(ERROR_MSG_MISSING_OUTPUT_FORMAT, JOB_SUBMIT_DOC_LINK_MSG) # An entry point is required on QIR jobs - # if job_type == QIR_JOB and entry_point is None and ("entryPoint" not in job_params.keys() or job_params["entryPoint"] is None): - # raise RequiredArgumentMissingError(ERROR_MSG_MISSING_ENTRY_POINT, JOB_SUBMIT_DOC_LINK_MSG) if job_type == QIR_JOB: - # An entry point is required for a QIR job, but there are four ways to specify it: + # An entry point is required for a QIR job, but there are four ways to specify it in a CLI command: # - Use the --entry-point parameter # - Include it in --job-params as entryPoint=MyEntryPoint # - Include it as 'entryPoint':'MyEntryPoint' in a JSON --job-params string or file From d9be1dc53a3239c99809dd735825a25a2068cee2 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Fri, 27 Jan 2023 15:29:51 -0800 Subject: [PATCH 63/65] Rename storage.py to _storage.py --- src/quantum/azext_quantum/{storage.py => _storage.py} | 3 ++- src/quantum/azext_quantum/operations/job.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename src/quantum/azext_quantum/{storage.py => _storage.py} (95%) diff --git a/src/quantum/azext_quantum/storage.py b/src/quantum/azext_quantum/_storage.py similarity index 95% rename from src/quantum/azext_quantum/storage.py rename to src/quantum/azext_quantum/_storage.py index d98a5464382..bb372186112 100644 --- a/src/quantum/azext_quantum/storage.py +++ b/src/quantum/azext_quantum/_storage.py @@ -3,8 +3,9 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -# This file is a reduced version of qdk-python/azure-quantum/azure/quantum/target/target.py +# This file is a reduced version of qdk-python\azure-quantum\azure\quantum\storage.py # It only contains the functions required to do inputData blob upload for job submission. +# Other cosmetic changes were made to appease the Azure CLI CI/CD checks. # Unused imports were removed to reduce Pylint style-rule violations. import logging diff --git a/src/quantum/azext_quantum/operations/job.py b/src/quantum/azext_quantum/operations/job.py index 4eb5f6d7dd6..73219cf489d 100644 --- a/src/quantum/azext_quantum/operations/job.py +++ b/src/quantum/azext_quantum/operations/job.py @@ -18,7 +18,7 @@ InvalidArgumentValueError, AzureResponseError, RequiredArgumentMissingError) -from ..storage import create_container, upload_blob +from .._storage import create_container, upload_blob from .._client_factory import cf_jobs, _get_data_credentials from .workspace import WorkspaceInfo From c7af32428ea820d1d63984af4c6110674a40c4ba Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 31 Jan 2023 11:39:16 -0800 Subject: [PATCH 64/65] Increase min CLI core version to 2.41.0 --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/azext_quantum/azext_metadata.json | 2 +- src/quantum/setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index 8bacf10f915..9fdd3a7406f 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.17.0.3" +CLI_REPORTED_VERSION = "0.17.0.4" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/azext_quantum/azext_metadata.json b/src/quantum/azext_quantum/azext_metadata.json index 811d86de250..40dc71e5e71 100644 --- a/src/quantum/azext_quantum/azext_metadata.json +++ b/src/quantum/azext_quantum/azext_metadata.json @@ -1,4 +1,4 @@ { "azext.isPreview": true, - "azext.minCliCoreVersion": "2.23.0" + "azext.minCliCoreVersion": "2.41.0" } diff --git a/src/quantum/setup.py b/src/quantum/setup.py index a787b4c376a..478075f80ae 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.17.0.3' +VERSION = '0.17.0.4' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From 3cf27dcbc79a5c2c15325f7446f5f676b1a7a4b1 Mon Sep 17 00:00:00 2001 From: Warren Jones Date: Tue, 31 Jan 2023 17:27:50 -0800 Subject: [PATCH 65/65] Restore version numbers in preparation for merge --- src/quantum/azext_quantum/__init__.py | 2 +- src/quantum/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quantum/azext_quantum/__init__.py b/src/quantum/azext_quantum/__init__.py index 9fdd3a7406f..cc51ac7daca 100644 --- a/src/quantum/azext_quantum/__init__.py +++ b/src/quantum/azext_quantum/__init__.py @@ -11,7 +11,7 @@ # This is the version reported by the CLI to the service when submitting requests. # This should be in sync with the extension version in 'setup.py', unless we need to # submit using a different version. -CLI_REPORTED_VERSION = "0.17.0.4" +CLI_REPORTED_VERSION = "0.17.0" class QuantumCommandsLoader(AzCommandsLoader): diff --git a/src/quantum/setup.py b/src/quantum/setup.py index 478075f80ae..5e99e30432c 100644 --- a/src/quantum/setup.py +++ b/src/quantum/setup.py @@ -17,7 +17,7 @@ # This version should match the latest entry in HISTORY.rst # Also, when updating this, please review the version used by the extension to # submit requests, which can be found at './azext_quantum/__init__.py' -VERSION = '0.17.0.4' +VERSION = '0.17.0' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers