From ffd2781b80e4ec6a7d6215a8a17394a171fb8630 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 28 Feb 2024 14:07:48 +0200 Subject: [PATCH 01/51] Partial version of EstimatorV2 input schema --- schemas/estimator_v2_schema.json | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 schemas/estimator_v2_schema.json diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json new file mode 100644 index 0000000..7241e62 --- /dev/null +++ b/schemas/estimator_v2_schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://www.qiskit.org/schemas/estimator_v2_schema.json", + "title": "EstimatorV2 input", + "description": "The input for an EstimatorV2 API call", + "version": "1.0.0", + "type": "object", + "required": ["pubs"], + "properties": { + "pubs": { + "type": "array", + "description": "Circuits/Observbles/Parameters to run", + "items": { + "type": "array", + "prefixItems": [ + {"description": "The quantum circuit", "type": "object"}, + {"description": "The observable array", "type": "object"}, + {"description": "The parameter values", "type": "object"} + ] + } + }, + "transpilation": { + "description": "Transpilation settings.", + "type": "object", + "properties": { + "optimization_level": { + "description": "How much optimization to perform on the circuits", + "type": "integer", + "enum": [0, 1] + } + } + }, + "resilience_level": { + "description": "How much resilience to build against errors", + "type": "integer", + "enum": [0, 1, 2] + }, + "resilience": { + "description": "Advanced resilience options to fine tune the resilience strategy", + "type": "object", + "properties": { + "measure_noise_mitigation": { + "description": "Whether to enable measurement error mitigation method", + "type": "boolean" + }, + "zne_mitigation": { + "description": "Whether to turn on Zero Noise Extrapolation error mitigation method", + "type": "boolean" + }, + "zne_noise_factors": { + "description": "A list of real valued noise factors that determine by what amount the circuits' noise is amplified", + "type": "array", + "items": { + "type": "number" + } + }, + "zne_extrapolator": { + "description": "A list of extrapolation strategies", + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "enum": ["exponential", "double_exponential", "linear", "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", "polynomial_degree_4"] + } + }, + { + "type": "string", + "enum": ["exponential", "double_exponential", "linear", "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", "polynomial_degree_4"] + } + ] + }, + "zne_stderr_threshold": { + "description": "A standard error threshold for accepting the ZNE result", + "type": "number" + } + } + } + } +} \ No newline at end of file From 183b361a5403fc0c4872836e8fb9b4e79faae185 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 29 Feb 2024 14:45:51 +0200 Subject: [PATCH 02/51] Full EstimatorV2 schema --- schemas/estimator_v2_schema.json | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 7241e62..04c1c08 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -75,6 +75,51 @@ "type": "number" } } + }, + "execution": { + "description": "Execution options", + "type": "object", + "properties": { + "shots": { + "description": "Number of repetitions of each circuit, for sampling", + "type": "number" + }, + "init_qubits": { + "description": "Whether to reset the qubits to the ground state for each shot", + "type": "boolean" + }, + "samples": { + "description": "The number of samples of each measurement circuit to run", + "type": "number" + }, + "shots_per_sample": { + "description": "The number of shots per sample of each measurement circuit to run", + "type": "number" + }, + "interleave_samples": { + "description": "Whether to interleave samples from different measurement circuits when running or run them in order", + "type": "boolean" + } + } + }, + "twirling": { + "description": "Twirling options", + "type": "object", + "properties": { + "gates": { + "description": "Whether to apply 2-qubit gate twirling", + "type": "boolean" + }, + "measure": { + "description": "Whether to apply measurement twirling", + "type": "boolean" + }, + "strategy": { + "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", + "type": "string", + "enum": ["active", "active-circuit", "active-accum", "all"] + } + } } } } \ No newline at end of file From 299d7c279ab138541575c600a14dc398546ae883 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 29 Feb 2024 15:02:10 +0200 Subject: [PATCH 03/51] Added SamplerV2 schema and added `seed_estimator` to estimator schema --- schemas/estimator_v2_schema.json | 6 ++- schemas/sampler_v2_schema.json | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 schemas/sampler_v2_schema.json diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 04c1c08..1be0bdd 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -19,8 +19,12 @@ ] } }, + "seed_estimator": { + "description": "Seed used to control sampling", + "type": "integer" + }, "transpilation": { - "description": "Transpilation settings.", + "description": "Transpilation settings", "type": "object", "properties": { "optimization_level": { diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json new file mode 100644 index 0000000..80e7634 --- /dev/null +++ b/schemas/sampler_v2_schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://www.qiskit.org/schemas/sampler_v2_schema.json", + "title": "SamplerV2 input", + "description": "The input for an SamplerV2 API call", + "version": "1.0.0", + "type": "object", + "required": ["pubs"], + "properties": { + "pubs": { + "type": "array", + "description": "Circuits/Parameters to run", + "items": { + "type": "array", + "prefixItems": [ + {"description": "The quantum circuit", "type": "object"}, + {"description": "The parameter values", "type": "object"} + ] + } + }, + "transpilation": { + "description": "Transpilation settings.", + "type": "object", + "properties": { + "optimization_level": { + "description": "How much optimization to perform on the circuits", + "type": "integer", + "enum": [0, 1] + } + } + }, + "execution": { + "description": "Execution options", + "type": "object", + "properties": { + "shots": { + "description": "Number of repetitions of each circuit, for sampling", + "type": "number" + }, + "init_qubits": { + "description": "Whether to reset the qubits to the ground state for each shot", + "type": "boolean" + }, + "samples": { + "description": "The number of samples of each measurement circuit to run", + "type": "number" + }, + "shots_per_sample": { + "description": "The number of shots per sample of each measurement circuit to run", + "type": "number" + }, + "interleave_samples": { + "description": "Whether to interleave samples from different measurement circuits when running or run them in order", + "type": "boolean" + } + } + }, + "twirling": { + "description": "Twirling options", + "type": "object", + "properties": { + "gates": { + "description": "Whether to apply 2-qubit gate twirling", + "type": "boolean" + }, + "measure": { + "description": "Whether to apply measurement twirling", + "type": "boolean" + }, + "strategy": { + "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", + "type": "string", + "enum": ["active", "active-circuit", "active-accum", "all"] + } + } + } + } +} \ No newline at end of file From 377e168b4992adb1be70587c4bf984983c152c56 Mon Sep 17 00:00:00 2001 From: gadial Date: Mon, 11 Mar 2024 11:35:54 +0200 Subject: [PATCH 04/51] Updating the estimator schema after options changes in qiskit runtime --- schemas/estimator_v2_schema.json | 315 ++++++++++++++++++++++--------- 1 file changed, 225 insertions(+), 90 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 1be0bdd..d0b2e1b 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -19,109 +19,244 @@ ] } }, - "seed_estimator": { - "description": "Seed used to control sampling", - "type": "integer" - }, - "transpilation": { - "description": "Transpilation settings", - "type": "object", - "properties": { - "optimization_level": { - "description": "How much optimization to perform on the circuits", - "type": "integer", - "enum": [0, 1] - } - } - }, - "resilience_level": { - "description": "How much resilience to build against errors", - "type": "integer", - "enum": [0, 1, 2] - }, - "resilience": { - "description": "Advanced resilience options to fine tune the resilience strategy", + "options": { "type": "object", + "description": "Options for V2 Estimator", "properties": { - "measure_noise_mitigation": { - "description": "Whether to enable measurement error mitigation method", - "type": "boolean" + "seed_estimator": { + "description": "Seed used to control sampling", + "type": "integer" }, - "zne_mitigation": { - "description": "Whether to turn on Zero Noise Extrapolation error mitigation method", - "type": "boolean" + "default_precision": { + "description": "The default precision to use for any PUB that does not specify one", + "type": "number" }, - "zne_noise_factors": { - "description": "A list of real valued noise factors that determine by what amount the circuits' noise is amplified", - "type": "array", - "items": { - "type": "number" - } + "default_shots": { + "description": "The total number of shots to use per circuit per configuration", + "type": "integer" }, - "zne_extrapolator": { - "description": "A list of extrapolation strategies", - "oneOf": [ - { - "type": "array", - "items": { - "type": "string", - "enum": ["exponential", "double_exponential", "linear", "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", "polynomial_degree_4"] - } + "dynamical_decoupling": { + "description": "Suboptions for dynamical decoupling", + "type": "object", + "properties": { + "enable": { + "description": "Whether to enable DD as specified by the other options in this class", + "type": "boolean" + }, + "sequence_type": { + "description": "Which dynamical decoupling sequence to use", + "type": "string", + "enum": ["XX", "XpXm", "XY4"] + }, + "extra_slack_distribution": { + "description": "Where to put extra timing delays due to rounding issues", + "type": "string", + "enum": ["middle", "edges"] }, - { + "scheduling_method": { + "description": "Whether to schedule gates as soon as ('asap') or as late as ('alap') possible", "type": "string", - "enum": ["exponential", "double_exponential", "linear", "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", "polynomial_degree_4"] + "enum": ["alap", "asap"] } - ] - }, - "zne_stderr_threshold": { - "description": "A standard error threshold for accepting the ZNE result", - "type": "number" - } - } - }, - "execution": { - "description": "Execution options", - "type": "object", - "properties": { - "shots": { - "description": "Number of repetitions of each circuit, for sampling", - "type": "number" - }, - "init_qubits": { - "description": "Whether to reset the qubits to the ground state for each shot", - "type": "boolean" + } }, - "samples": { - "description": "The number of samples of each measurement circuit to run", - "type": "number" + "transpilation": { + "description": "Transpilation settings", + "type": "object", + "properties": { + "optimization_level": { + "description": "How much optimization to perform on the circuits", + "type": "integer", + "enum": [ + 0, + 1 + ] + } + } }, - "shots_per_sample": { - "description": "The number of shots per sample of each measurement circuit to run", - "type": "number" + "resilience_level": { + "description": "How much resilience to build against errors", + "type": "integer", + "enum": [ + 0, + 1, + 2 + ] }, - "interleave_samples": { - "description": "Whether to interleave samples from different measurement circuits when running or run them in order", - "type": "boolean" - } - } - }, - "twirling": { - "description": "Twirling options", - "type": "object", - "properties": { - "gates": { - "description": "Whether to apply 2-qubit gate twirling", - "type": "boolean" + "resilience": { + "description": "Advanced resilience options to fine tune the resilience strategy", + "type": "object", + "properties": { + "measure_mitigation": { + "description": "Whether to enable measurement error mitigation method", + "type": "boolean" + }, + "measure_noise_learning": { + "description": "Additional measurement noise learning options", + "type": "object", + "properties": { + "num_randomizations": { + "description": "The number of random circuits to draw for the measurement learning experiment", + "type": "integer" + }, + "shots_per_randomization": { + "description": "The number of shots to use for the learning experiment per random circuit.", + "oneOf": [{"type": "integer"}, {"enum": "auto"}] + } + } + }, + "zne_mitigation": { + "description": "Whether to turn on Zero Noise Extrapolation error mitigation method", + "type": "boolean" + }, + "zne": { + "description": "Additional zero noise extrapolation mitigation options", + "type": "object", + "properties": { + "zne_noise_factors": { + "description": "Noise factors to use for noise amplification", + "type": "array", + "items": { + "type": "number" + } + }, + "zne_extrapolator": { + "description": "Extrapolator(s) to try (in order) for extrapolating to zero noise", + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "linear", + "exponential", + "double_exponential", + "polynomial_degree_1", + "polynomial_degree_2", + "polynomial_degree_3", + "polynomial_degree_4", + "polynomial_degree_5", + "polynomial_degree_6", + "polynomial_degree_7" + ] + } + }, + { + "type": "string", + "enum": [ + "linear", + "exponential", + "double_exponential", + "polynomial_degree_1", + "polynomial_degree_2", + "polynomial_degree_3", + "polynomial_degree_4", + "polynomial_degree_5", + "polynomial_degree_6", + "polynomial_degree_7" + ] + } + ] + } + } + }, + "pec_mitigation": { + "description": "Whether to turn on Probabilistic Error Cancellation error mitigation method", + "type": "boolean" + }, + "pec": { + "description": "Additional probabalistic error cancellation mitigation options", + "type": "object", + "properties": { + "max_overhead": { + "description": "The maximum circuit sampling overhead allowed", + "oneOf": [ + {"type": "number"}, + {"type": "null"} + ] + }, + "noise_gain": { + "description": "The amount by which to scale the noise", + "oneOf": [ + {"type": "numebr"}, + {"enum": ["auto"]} + ] + } + } + }, + "layer_noise_learning": { + "description": "Layer noise learning options", + "type": "object", + "properties": { + "max_layers_to_learn": { + "description": "The max number of unique layers to learn", + "type": "integer" + }, + "shots_per_randomization": { + "description": "The total number of shots to use per random learning circuit", + "type": "integer" + }, + "num_randomizations": { + "description": "The number of random circuits to use per learning circuit configuration", + "type": "integer" + }, + "layer_pair_depths": { + "description": "The circuit depths (measured in number of pairs) to use in learning experiments", + "type": "array", + "items": { + "type": "integer" + } + } + } + } + + } }, - "measure": { - "description": "Whether to apply measurement twirling", - "type": "boolean" + "execution": { + "description": "Execution options", + "type": "object", + "properties": { + "init_qubits": { + "description": "Whether to reset the qubits to the ground state for each shot", + "type": "boolean" + }, + "rep_delay": { + "description": "The delay between a measurement and the subsequent quantum circuit", + "type": "number" + } + } }, - "strategy": { - "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", - "type": "string", - "enum": ["active", "active-circuit", "active-accum", "all"] + "twirling": { + "description": "Twirling options", + "type": "object", + "properties": { + "enable_gates": { + "description": "Whether to apply 2-qubit gate twirling", + "type": "boolean" + }, + "enable_measure": { + "description": "Whether to apply measurement twirling", + "type": "boolean" + }, + "num_randomizations": { + "description": "The number of random samples to use when twirling or performing sampled mitigation", + "oneOf": [{"type": "integer"}, {"enum": ["auto"]}] + }, + "shots_per_randomization": { + "description": "The number of shots to run for each random sample", + "oneOf": [{"type": "integer"}, {"enum": ["auto"]}] + }, + "strategy": { + "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", + "type": "string", + "enum": [ + "active", + "active-circuit", + "active-accum", + "all" + ] + } + } } } } From 3e046dd2ea84997f8a82c0f8ce063d55c38d4a3e Mon Sep 17 00:00:00 2001 From: gadial Date: Mon, 11 Mar 2024 11:39:00 +0200 Subject: [PATCH 05/51] Updated SamplerV2 schema --- schemas/sampler_v2_schema.json | 103 ++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 80e7634..c65ba76 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -18,60 +18,67 @@ ] } }, - "transpilation": { - "description": "Transpilation settings.", - "type": "object", - "properties": { - "optimization_level": { - "description": "How much optimization to perform on the circuits", - "type": "integer", - "enum": [0, 1] - } - } - }, - "execution": { - "description": "Execution options", + "options": { "type": "object", + "description": "Options for V2 Sampler", "properties": { - "shots": { - "description": "Number of repetitions of each circuit, for sampling", - "type": "number" - }, - "init_qubits": { - "description": "Whether to reset the qubits to the ground state for each shot", - "type": "boolean" + "default_shots": { + "description": "The default number of shots to use if none are specified in the PUBs", + "type": "integer" }, - "samples": { - "description": "The number of samples of each measurement circuit to run", - "type": "number" + "dynamical_decoupling": { + "description": "Suboptions for dynamical decoupling", + "type": "object", + "properties": { + "enable": { + "description": "Whether to enable DD as specified by the other options in this class", + "type": "boolean" + }, + "sequence_type": { + "description": "Which dynamical decoupling sequence to use", + "type": "string", + "enum": ["XX", "XpXm", "XY4"] + }, + "extra_slack_distribution": { + "description": "Where to put extra timing delays due to rounding issues", + "type": "string", + "enum": ["middle", "edges"] + }, + "scheduling_method": { + "description": "Whether to schedule gates as soon as ('asap') or as late as ('alap') possible", + "type": "string", + "enum": ["alap", "asap"] + } + } }, - "shots_per_sample": { - "description": "The number of shots per sample of each measurement circuit to run", - "type": "number" - }, - "interleave_samples": { - "description": "Whether to interleave samples from different measurement circuits when running or run them in order", - "type": "boolean" - } - } - }, - "twirling": { - "description": "Twirling options", - "type": "object", - "properties": { - "gates": { - "description": "Whether to apply 2-qubit gate twirling", - "type": "boolean" + "transpilation": { + "description": "Transpilation settings", + "type": "object", + "properties": { + "optimization_level": { + "description": "How much optimization to perform on the circuits", + "type": "integer", + "enum": [ + 0, + 1 + ] + } + } }, - "measure": { - "description": "Whether to apply measurement twirling", - "type": "boolean" + "execution": { + "description": "Execution options", + "type": "object", + "properties": { + "init_qubits": { + "description": "Whether to reset the qubits to the ground state for each shot", + "type": "boolean" + }, + "rep_delay": { + "description": "The delay between a measurement and the subsequent quantum circuit", + "type": "number" + } + } }, - "strategy": { - "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", - "type": "string", - "enum": ["active", "active-circuit", "active-accum", "all"] - } } } } From c565ff8bbfea2c2d3559ce8b52c444742e524b41 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 13 Mar 2024 09:04:18 +0200 Subject: [PATCH 06/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index d0b2e1b..9b7cb2d 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -13,7 +13,7 @@ "items": { "type": "array", "prefixItems": [ - {"description": "The quantum circuit", "type": "object"}, + {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, {"description": "The observable array", "type": "object"}, {"description": "The parameter values", "type": "object"} ] From 18494436440056cfcae71f747c8d474bd539e021 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 13 Mar 2024 09:04:56 +0200 Subject: [PATCH 07/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 9b7cb2d..6fc6452 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -14,7 +14,7 @@ "type": "array", "prefixItems": [ {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, - {"description": "The observable array", "type": "object"}, + {"description": "One or more observables.", "type": "array"}, {"description": "The parameter values", "type": "object"} ] } From 18af181d11bb32b14776b031cd92293961c776cf Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 13 Mar 2024 09:05:08 +0200 Subject: [PATCH 08/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 6fc6452..834fa2d 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -40,7 +40,7 @@ "type": "object", "properties": { "enable": { - "description": "Whether to enable DD as specified by the other options in this class", + "description": "Whether to enable dynamical decoupling.", "type": "boolean" }, "sequence_type": { From aed9bbed337b56b3a135f308d58bf5947581969e Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 13 Mar 2024 09:33:12 +0200 Subject: [PATCH 09/51] Fixes according to PR review --- schemas/estimator_v2_schema.json | 26 ++++++++++++++++---------- schemas/sampler_v2_schema.json | 24 ++++++++---------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 834fa2d..6895070 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -12,10 +12,12 @@ "description": "Circuits/Observbles/Parameters to run", "items": { "type": "array", + "minItems": 2, "prefixItems": [ {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, {"description": "One or more observables.", "type": "array"}, - {"description": "The parameter values", "type": "object"} + {"description": "The parameter values", "type": "object"}, + {"description": "The precision for this specific pub", "type": "number"} ] } }, @@ -74,15 +76,6 @@ } } }, - "resilience_level": { - "description": "How much resilience to build against errors", - "type": "integer", - "enum": [ - 0, - 1, - 2 - ] - }, "resilience": { "description": "Advanced resilience options to fine tune the resilience strategy", "type": "object", @@ -259,6 +252,19 @@ } } } + }, + "resilience_level": { + "description": "How much resilience to build against errors", + "type": "integer", + "enum": [ + 0, + 1, + 2 + ] + }, + "version": { + "description": "For EstimatorV2, version should always be 2", + "enum": [2] } } } \ No newline at end of file diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index c65ba76..d51a2e4 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -12,9 +12,11 @@ "description": "Circuits/Parameters to run", "items": { "type": "array", + "minItems": 1, "prefixItems": [ {"description": "The quantum circuit", "type": "object"}, - {"description": "The parameter values", "type": "object"} + {"description": "The parameter values", "type": "object"}, + {"description": "The numebr of shots to use in this pub", "type": "integer"} ] } }, @@ -51,20 +53,6 @@ } } }, - "transpilation": { - "description": "Transpilation settings", - "type": "object", - "properties": { - "optimization_level": { - "description": "How much optimization to perform on the circuits", - "type": "integer", - "enum": [ - 0, - 1 - ] - } - } - }, "execution": { "description": "Execution options", "type": "object", @@ -78,8 +66,12 @@ "type": "number" } } - }, + } } + }, + "version": { + "description": "For SamplerV2, version should always be 2", + "enum": [2] } } } \ No newline at end of file From bcf6256522f480770155aa808444be96afd8fb1f Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:13 +0300 Subject: [PATCH 10/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 6895070..32d92f3 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -35,7 +35,8 @@ }, "default_shots": { "description": "The total number of shots to use per circuit per configuration", - "type": "integer" + "type": "integer", + "minimum": 0 }, "dynamical_decoupling": { "description": "Suboptions for dynamical decoupling", From 337867e0fc0e83761d32a818d3efe755b08d5697 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:19 +0300 Subject: [PATCH 11/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 32d92f3..9295368 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -34,7 +34,7 @@ "type": "number" }, "default_shots": { - "description": "The total number of shots to use per circuit per configuration", + "description": "The total number of shots to use per circuit per configuration. If set, this value overrides default_precision.", "type": "integer", "minimum": 0 }, From 8d946fa374686aeae3376e28fb6e4033f8383dde Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:33 +0300 Subject: [PATCH 12/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 9295368..a68123f 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -91,7 +91,8 @@ "properties": { "num_randomizations": { "description": "The number of random circuits to draw for the measurement learning experiment", - "type": "integer" + "type": "integer", + "minimum": 1 }, "shots_per_randomization": { "description": "The number of shots to use for the learning experiment per random circuit.", From 82609b6a0b01955538af8b899b83a7eb6ea7d920 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:40 +0300 Subject: [PATCH 13/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index a68123f..38f8759 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -16,7 +16,7 @@ "prefixItems": [ {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, {"description": "One or more observables.", "type": "array"}, - {"description": "The parameter values", "type": "object"}, + {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The precision for this specific pub", "type": "number"} ] } From 255fcd7c3df66dcfbf38d977e78153fe374b0cd9 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:51 +0300 Subject: [PATCH 14/51] Update schemas/sampler_v2_schema.json Co-authored-by: Jessie Yu --- schemas/sampler_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index d51a2e4..66e8a86 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -15,7 +15,7 @@ "minItems": 1, "prefixItems": [ {"description": "The quantum circuit", "type": "object"}, - {"description": "The parameter values", "type": "object"}, + {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The numebr of shots to use in this pub", "type": "integer"} ] } From 1886b62583698050be4dd70c303f030937aa84ff Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:28:59 +0300 Subject: [PATCH 15/51] Update schemas/sampler_v2_schema.json Co-authored-by: Jessie Yu --- schemas/sampler_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 66e8a86..1e95e1d 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -14,7 +14,7 @@ "type": "array", "minItems": 1, "prefixItems": [ - {"description": "The quantum circuit", "type": "object"}, + {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The numebr of shots to use in this pub", "type": "integer"} ] From 141f86ce9c6374a7d10f198413662450a45040b6 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:29:09 +0300 Subject: [PATCH 16/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 38f8759..c4c51eb 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -31,7 +31,8 @@ }, "default_precision": { "description": "The default precision to use for any PUB that does not specify one", - "type": "number" + "type": "number", + "exclusiveMinimum": 0 }, "default_shots": { "description": "The total number of shots to use per circuit per configuration. If set, this value overrides default_precision.", From 158e3ff7139ef95b646bbdb4ddcd11978a103c26 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:29:22 +0300 Subject: [PATCH 17/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index c4c51eb..a07c6e4 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -97,7 +97,7 @@ }, "shots_per_randomization": { "description": "The number of shots to use for the learning experiment per random circuit.", - "oneOf": [{"type": "integer"}, {"enum": "auto"}] + "oneOf": [{"type": "integer", "minimum": 1}, {"enum": "auto"}] } } }, From a63eb71fd192ffaa63664e6a7fba9efddf292270 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:29:31 +0300 Subject: [PATCH 18/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index a07c6e4..edb5108 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -167,7 +167,7 @@ "max_overhead": { "description": "The maximum circuit sampling overhead allowed", "oneOf": [ - {"type": "number"}, + {"type": "number", "exclusiveMinimum": 0}, {"type": "null"} ] }, From 1c1e6f8e9d424067bbc92b8080d6a579aa6b1053 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:29:45 +0300 Subject: [PATCH 19/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index edb5108..89a6a81 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -174,7 +174,7 @@ "noise_gain": { "description": "The amount by which to scale the noise", "oneOf": [ - {"type": "numebr"}, + {"type": "number", "exclusiveMinimum": 0}, {"enum": ["auto"]} ] } From 126276d337043e2a6be54cf1fcb31e198ac4f92d Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:29:56 +0300 Subject: [PATCH 20/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 89a6a81..bb53d8e 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -186,7 +186,8 @@ "properties": { "max_layers_to_learn": { "description": "The max number of unique layers to learn", - "type": "integer" + "type": "integer", + "minimum": 0 }, "shots_per_randomization": { "description": "The total number of shots to use per random learning circuit", From e3c233b5c9b58b530bebfcc8dd8c991c06d00579 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:30:05 +0300 Subject: [PATCH 21/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index bb53d8e..f342523 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -191,7 +191,8 @@ }, "shots_per_randomization": { "description": "The total number of shots to use per random learning circuit", - "type": "integer" + "type": "integer", + "minimum": 1 }, "num_randomizations": { "description": "The number of random circuits to use per learning circuit configuration", From 3f284dc7ff93a0279c4be2c81084a58154f9af6a Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:30:16 +0300 Subject: [PATCH 22/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index f342523..5cf3482 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -196,7 +196,8 @@ }, "num_randomizations": { "description": "The number of random circuits to use per learning circuit configuration", - "type": "integer" + "type": "integer", + "minimum": 1 }, "layer_pair_depths": { "description": "The circuit depths (measured in number of pairs) to use in learning experiments", From 9ce0aeb642462f29187a7beae5b71be0fd9d5764 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:30:27 +0300 Subject: [PATCH 23/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 5cf3482..b776cd6 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -203,7 +203,8 @@ "description": "The circuit depths (measured in number of pairs) to use in learning experiments", "type": "array", "items": { - "type": "integer" + "type": "integer", + "minimum": 0 } } } From 5ccb378dea290e020297d9f23982baf8912a70b7 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:30:35 +0300 Subject: [PATCH 24/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index b776cd6..1b2bbbb 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -240,7 +240,7 @@ }, "num_randomizations": { "description": "The number of random samples to use when twirling or performing sampled mitigation", - "oneOf": [{"type": "integer"}, {"enum": ["auto"]}] + "oneOf": [{"type": "integer", "minimum": 1}, {"enum": ["auto"]}] }, "shots_per_randomization": { "description": "The number of shots to run for each random sample", From 420d814aff495a87f5de3dc8dba539cf9b9130e9 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 09:30:45 +0300 Subject: [PATCH 25/51] Update schemas/estimator_v2_schema.json Co-authored-by: Jessie Yu --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 1b2bbbb..6381ef2 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -244,7 +244,7 @@ }, "shots_per_randomization": { "description": "The number of shots to run for each random sample", - "oneOf": [{"type": "integer"}, {"enum": ["auto"]}] + "oneOf": [{"type": "integer", "minimum": 1}, {"enum": ["auto"]}] }, "strategy": { "description": "The strategy of twirling qubits in identified layers of 2-qubit twirled gates", From 55a7c674c5d96cd4fa81fe113d40f291d1b2e7bf Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 10:14:08 +0300 Subject: [PATCH 26/51] Starting to add tests --- requirements-dev.txt | 1 + tests/test_primitive_schemas.py | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/test_primitive_schemas.py diff --git a/requirements-dev.txt b/requirements-dev.txt index 81b9788..cf00324 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,3 +2,4 @@ fastjsonschema jsonschema jsonschema-rs ddt +qiskit-ibm-runtime>=0.22 \ No newline at end of file diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py new file mode 100644 index 0000000..4cfda95 --- /dev/null +++ b/tests/test_primitive_schemas.py @@ -0,0 +1,65 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2024 +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +import json +import os +import unittest +import ddt +from dataclasses import asdict +import jsonschema + + +from qiskit_ibm_runtime import SamplerV2, EstimatorV2 + +SCHEMAS_PATH = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + 'schemas') + +@ddt.ddt +class TestEstimatorV2Schema(unittest.TestCase): + """Tests the estimator schema agrees with the format of the qiskit runtime estimator API calls""" + def setUp(self) -> None: + with open(os.path.join(SCHEMAS_PATH, 'estimator_v2_schema.json'), 'r') as fd: + self.estimator_schema = json.load(fd) + self.validator = jsonschema.Draft4Validator(schema=self.estimator_schema) + self.backend = "ibmq_qasm_simulator" + + @staticmethod + def get_options_dict(estimator): + """Emulate the process in `qiskit-ibm-runtime` where the EstimatorOptions + are converted to a filtered options dictionary""" + options_dict = estimator.options._get_program_inputs(asdict(estimator.options)) + if 'pubs' not in options_dict: + options_dict['pubs'] = [] + return options_dict + def test_basic(self): + """Testing the bare-bones options for an estimator""" + estimator = EstimatorV2(backend=self.backend) + options = self.get_options_dict(estimator) + self.assertIsNone(self.validator.validate(options)) + + @ddt.data(0, 1, 2, 3, -1, 17, 3.5) + def test_resilience_level(self, level): + """Testing various valeus of the resilience level""" + estimator = EstimatorV2(backend=self.backend) + try: + estimator.options.resilience_level = level + options = self.get_options_dict(estimator) + self.assertIsNone(self.validator.validate(options)) + except Exception: + # If the estimator's inner option validation failed + # verify our own validation fail as well + options = self.get_options_dict(estimator) + options['resilience_level'] = level + self.assertFalse(self.validator.is_valid(options)) + + From 6913d3d4a995ff9e749df0896cd4eee8d5d134e0 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 3 Apr 2024 11:49:11 +0300 Subject: [PATCH 27/51] Added a framework to test schema vs runtime validator --- tests/test_primitive_schemas.py | 56 ++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 4cfda95..df47ab8 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -30,7 +30,7 @@ class TestEstimatorV2Schema(unittest.TestCase): def setUp(self) -> None: with open(os.path.join(SCHEMAS_PATH, 'estimator_v2_schema.json'), 'r') as fd: self.estimator_schema = json.load(fd) - self.validator = jsonschema.Draft4Validator(schema=self.estimator_schema) + self.validator = jsonschema.Draft202012Validator(schema=self.estimator_schema) self.backend = "ibmq_qasm_simulator" @staticmethod @@ -41,6 +41,24 @@ def get_options_dict(estimator): if 'pubs' not in options_dict: options_dict['pubs'] = [] return options_dict + + def assert_valid_options(self, estimator, options_to_check, options_path=""): + """Verifies the schema validation gives the same result as attempting + to set the options in the estimator""" + options = estimator.options + try: + for option_name, value in options_to_check.items(): + setattr(options, option_name, value) + options_dict = TestEstimatorV2Schema.get_options_dict(estimator) + self.assertTrue(self.validator.is_valid(options_dict)) + except Exception: + options_dict = TestEstimatorV2Schema.get_options_dict(estimator) + for option_name, value in options_to_check.items(): + dict_to_change = options_dict + for key in options_path: + dict_to_change = dict_to_change[key] + dict_to_change[option_name] = value + self.assertFalse(self.validator.is_valid(options_dict)) def test_basic(self): """Testing the bare-bones options for an estimator""" estimator = EstimatorV2(backend=self.backend) @@ -49,17 +67,31 @@ def test_basic(self): @ddt.data(0, 1, 2, 3, -1, 17, 3.5) def test_resilience_level(self, level): - """Testing various valeus of the resilience level""" + """Testing various values of the resilience level""" estimator = EstimatorV2(backend=self.backend) - try: - estimator.options.resilience_level = level - options = self.get_options_dict(estimator) - self.assertIsNone(self.validator.validate(options)) - except Exception: - # If the estimator's inner option validation failed - # verify our own validation fail as well - options = self.get_options_dict(estimator) - options['resilience_level'] = level - self.assertFalse(self.validator.is_valid(options)) + options_to_set = {'resilience_level': level} + self.assert_valid_options(estimator, options_to_set) + @ddt.data(0, 1, 3.5) + def test_seed_estimator(self, seed): + """Testing various values of the seed estimator""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options'] + options_to_set = {'seed_estimator': seed} + self.assert_valid_options(estimator, options_to_set, options_path) + + @ddt.data(0, 1, 3.5) + def test_default_precision(self, precision): + """Testing various values of the default precision""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options'] + options_to_set = {'default_precision': precision} + self.assert_valid_options(estimator, options_to_set, options_path) + @ddt.data(0, 1, 3.5, -2) + def test_default_shots(self, shots): + """Testing various values of the default shots""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options'] + options_to_set = {'default_shots': shots} + self.assert_valid_options(estimator, options_to_set, options_path) From 54ab15d2acb74e8dd0f678d6ee3f7cfea355c590 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 4 Apr 2024 15:09:02 +0300 Subject: [PATCH 28/51] Added dynamical decoupling tests and fixed some bugs in the framework --- tests/__init__.py | 50 +++++++++++++++++++++++++++++++++ tests/test_primitive_schemas.py | 30 ++++++++++++++++++-- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..157a575 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,50 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""With some utils""" + +import itertools +from ddt import data, unpack + +class Case(dict): + """""" + + +def generate_cases(docstring, dsc=None, name=None, **kwargs): + """Combines kwargs in Cartesian product and creates Case with them""" + ret = [] + keys = kwargs.keys() + vals = kwargs.values() + for values in itertools.product(*vals): + case = Case(zip(keys, values)) + if docstring is not None: + setattr(case, "__doc__", docstring.format(**case)) + if dsc is not None: + setattr(case, "__doc__", dsc.format(**case)) + if name is not None: + setattr(case, "__name__", name.format(**case)) + ret.append(case) + return ret + + +def combine(**kwargs): + """Decorator to create combinations and tests + @combine(level=[0, 1, 2, 3], + circuit=[a, b, c, d], + dsc='Test circuit {circuit.__name__} with level {level}', + name='{circuit.__name__}_level{level}') + """ + + def deco(func): + return data(*generate_cases(docstring=func.__doc__, **kwargs))(unpack(func)) + + return deco diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index df47ab8..9ed8ead 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -17,8 +17,8 @@ from dataclasses import asdict import jsonschema - from qiskit_ibm_runtime import SamplerV2, EstimatorV2 +from tests import combine SCHEMAS_PATH = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), @@ -42,20 +42,27 @@ def get_options_dict(estimator): options_dict['pubs'] = [] return options_dict - def assert_valid_options(self, estimator, options_to_check, options_path=""): + def assert_valid_options(self, estimator, options_to_check, options_path="", options_object=None): """Verifies the schema validation gives the same result as attempting to set the options in the estimator""" - options = estimator.options + if options_object is None: + options = estimator.options + else: + options = options_object try: for option_name, value in options_to_check.items(): setattr(options, option_name, value) options_dict = TestEstimatorV2Schema.get_options_dict(estimator) self.assertTrue(self.validator.is_valid(options_dict)) + except AssertionError as err: + raise err except Exception: options_dict = TestEstimatorV2Schema.get_options_dict(estimator) for option_name, value in options_to_check.items(): dict_to_change = options_dict for key in options_path: + if key not in dict_to_change: + dict_to_change[key] = {} dict_to_change = dict_to_change[key] dict_to_change[option_name] = value self.assertFalse(self.validator.is_valid(options_dict)) @@ -95,3 +102,20 @@ def test_default_shots(self, shots): options_path = ['options'] options_to_set = {'default_shots': shots} self.assert_valid_options(estimator, options_to_set, options_path) + + @combine(enable=[True, False, 13, "False"], + sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], + extra_slack_distribution=["middle", "edges", "end", 13], + scheduling_method=["alap", "asap", "lapsap", 13] + ) + def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribution, scheduling_method): + """Testing various values of dynamical decoupling""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options', 'dynamical_decoupling'] + options_to_set = { + 'enable': enable, + 'sequence_type': sequence_type, + 'extra_slack_distribution': extra_slack_distribution, + 'scheduling_method': scheduling_method + } + self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.dynamical_decoupling) From 7c1b9fcec5212ff84f9d1608e51a92a3b83ea6d8 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 4 Apr 2024 15:24:49 +0300 Subject: [PATCH 29/51] Test for resilience boolean values and schema fix based on the test --- schemas/estimator_v2_schema.json | 51 +++++++++++++++++++++++++++----- tests/test_primitive_schemas.py | 23 ++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 6381ef2..f63c771 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -97,7 +97,15 @@ }, "shots_per_randomization": { "description": "The number of shots to use for the learning experiment per random circuit.", - "oneOf": [{"type": "integer", "minimum": 1}, {"enum": "auto"}] + "oneOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "enum": "auto" + } + ] } } }, @@ -167,15 +175,27 @@ "max_overhead": { "description": "The maximum circuit sampling overhead allowed", "oneOf": [ - {"type": "number", "exclusiveMinimum": 0}, - {"type": "null"} + { + "type": "number", + "exclusiveMinimum": 0 + }, + { + "type": "null" + } ] }, "noise_gain": { "description": "The amount by which to scale the noise", "oneOf": [ - {"type": "number", "exclusiveMinimum": 0}, - {"enum": ["auto"]} + { + "type": "number", + "exclusiveMinimum": 0 + }, + { + "enum": [ + "auto" + ] + } ] } } @@ -209,8 +229,25 @@ } } } - - } + }, + "allOf": [ + { + "not": { + "required": [ + "zne_mitigation", + "pec_mitigation" + ], + "properties": { + "zne_mitigation": { + "const": true + }, + "pec_mitigation": { + "const": true + } + } + } + } + ] }, "execution": { "description": "Execution options", diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 9ed8ead..5950eff 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -119,3 +119,26 @@ def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribut 'scheduling_method': scheduling_method } self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.dynamical_decoupling) + + @ddt.data(0, 1, 3.5, -2) + def test_transpilation(self, optimization_level): + """Testing various values of the transpilation options""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options', 'transpilation'] + options_to_set = {'optimization_level': optimization_level} + self.assert_valid_options(estimator, options_to_set, options_path) + + @combine(measure_mitigation=[True, False, 13, "False"], + zne_mitigation=[True, False, 13, "False"], + pec_mitigation=[True, False, 13, "False"], + ) + def test_resilience(self, measure_mitigation, zne_mitigation, pec_mitigation): + """Testing various values of resilience""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options', 'resilience'] + options_to_set = { + 'measure_mitigation': measure_mitigation, + 'zne_mitigation': zne_mitigation, + 'pec_mitigation': pec_mitigation, + } + self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.resilience) From e3ff48a766237038d042b319753491e2167ab440 Mon Sep 17 00:00:00 2001 From: gadial Date: Fri, 5 Apr 2024 09:59:42 +0300 Subject: [PATCH 30/51] Tests for zne options; extended the schema to validate correct number of noise factors (currently disagrees with `EstimatorOptions` on behaviour in case of empty noise factor list) --- schemas/estimator_v2_schema.json | 241 ++++++++++++++++++++++++++++++- tests/test_primitive_schemas.py | 34 +++++ 2 files changed, 271 insertions(+), 4 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index f63c771..78f9e37 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -103,7 +103,7 @@ "minimum": 1 }, { - "enum": "auto" + "enum": ["auto"] } ] } @@ -117,14 +117,14 @@ "description": "Additional zero noise extrapolation mitigation options", "type": "object", "properties": { - "zne_noise_factors": { + "noise_factors": { "description": "Noise factors to use for noise amplification", "type": "array", "items": { "type": "number" } }, - "zne_extrapolator": { + "extrapolator": { "description": "Extrapolator(s) to try (in order) for extrapolating to zero noise", "oneOf": [ { @@ -162,7 +162,240 @@ } ] } - } + }, + "allOf": [ + { + "if": { + "$comment": "linear, exponential and polynomial_degree_1 require at least 2 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "anyOf": [ + {"const": "linear"}, + {"const": "exponential"}, + {"const": "polynomial_degree_1"} + ] + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "anyOf": [ + {"const": "linear"}, + {"const": "exponential"}, + {"const": "polynomial_degree_1"} + ] + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 2 + } + } + } + }, + { + "if": { + "$comment": "polynomial_degree_2 requires at least 3 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "const": "polynomial_degree_2" + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "const": "polynomial_degree_2" + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 3 + } + } + } + }, + { + "if": { + "$comment": "double_exponential and polynomial_degree_3 require at least 4 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "anyOf": [ + {"const": "double_exponential"}, + {"const": "polynomial_degree_3"} + ] + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "anyOf": [ + {"const": "double_exponential"}, + {"const": "polynomial_degree_3"} + ] + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 4 + } + } + } + }, + { + "if": { + "$comment": "polynomial_degree_4 requires at least 5 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "const": "polynomial_degree_4" + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "const": "polynomial_degree_4" + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 5 + } + } + } + }, + { + "if": { + "$comment": "polynomial_degree_5 requires at least 6 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "const": "polynomial_degree_5" + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "const": "polynomial_degree_5" + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 6 + } + } + } + }, + { + "if": { + "$comment": "polynomial_degree_6 requires at least 7 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "const": "polynomial_degree_6" + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "const": "polynomial_degree_6" + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 7 + } + } + } + }, + { + "if": { + "$comment": "polynomial_degree_7 requires at least 8 noise factors", + "anyOf": [ + { + "properties": { + "extrapolator": { + "const": "polynomial_degree_7" + } + } + }, + { + "properties": { + "extrapolator": { + "type": "array", + "contains": { + "const": "polynomial_degree_7" + } + } + } + } + ] + }, + "then": { + "properties": { + "noise_factors": { + "minItems": 8 + } + } + } + } + ] }, "pec_mitigation": { "description": "Whether to turn on Probabilistic Error Cancellation error mitigation method", diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 5950eff..4460788 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -53,6 +53,7 @@ def assert_valid_options(self, estimator, options_to_check, options_path="", opt for option_name, value in options_to_check.items(): setattr(options, option_name, value) options_dict = TestEstimatorV2Schema.get_options_dict(estimator) + print(options_dict) self.assertTrue(self.validator.is_valid(options_dict)) except AssertionError as err: raise err @@ -66,6 +67,7 @@ def assert_valid_options(self, estimator, options_to_check, options_path="", opt dict_to_change = dict_to_change[key] dict_to_change[option_name] = value self.assertFalse(self.validator.is_valid(options_dict)) + def test_basic(self): """Testing the bare-bones options for an estimator""" estimator = EstimatorV2(backend=self.backend) @@ -142,3 +144,35 @@ def test_resilience(self, measure_mitigation, zne_mitigation, pec_mitigation): 'pec_mitigation': pec_mitigation, } self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.resilience) + + @combine(num_randomizations=[0, 1, 2, True, "False"], + shots_per_randomization=[0, 1, 2, True, "False", "auto"], + ) + def test_measure_noise_learning(self, num_randomizations, shots_per_randomization): + """Testing various values of measure noise learning""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options', 'resilience', 'measure_noise_learning'] + options_to_set = { + 'num_randomizations': num_randomizations, + 'shots_per_randomization': shots_per_randomization, + } + self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.resilience.measure_noise_learning) + + @combine(noise_factors=[[17], [1,2], [1,4,8], [1.3, 3.2], False], + extrapolator=["linear", "exponential", "double_exponential", + "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", + "polynomial_degree_4", "polynomial_degree_5", "polynomial_degree_6", + "polynomial_degree_7", ["linear", "exponential", "polynomial_degree_3"], "false_extrapolator", + 13, False, [13, "linear"] + ] + ) + def test_zne_mitigation_options(self, noise_factors, extrapolator): + """Testing various values of measure noise learning""" + estimator = EstimatorV2(backend=self.backend) + options_path = ['options', 'resilience', 'zne'] + options_to_set = { + 'noise_factors': noise_factors, + 'extrapolator': extrapolator, + } + self.assert_valid_options(estimator, options_to_set, options_path, + estimator.options.resilience.zne) From ce5231b902903f189fed87fe2b82612fe9f9394a Mon Sep 17 00:00:00 2001 From: gadial Date: Mon, 8 Apr 2024 15:30:07 +0300 Subject: [PATCH 31/51] Improving the test framework --- tests/test_primitive_schemas.py | 168 ++++++++++++++------------------ 1 file changed, 71 insertions(+), 97 deletions(-) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 4460788..aa1f835 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -14,10 +14,9 @@ import os import unittest import ddt -from dataclasses import asdict import jsonschema -from qiskit_ibm_runtime import SamplerV2, EstimatorV2 +from qiskit_ibm_runtime import EstimatorOptions from tests import combine SCHEMAS_PATH = os.path.join( @@ -34,129 +33,101 @@ def setUp(self) -> None: self.backend = "ibmq_qasm_simulator" @staticmethod - def get_options_dict(estimator): + def get_converted_options(options_dict): """Emulate the process in `qiskit-ibm-runtime` where the EstimatorOptions are converted to a filtered options dictionary""" - options_dict = estimator.options._get_program_inputs(asdict(estimator.options)) - if 'pubs' not in options_dict: - options_dict['pubs'] = [] - return options_dict + converted_options = EstimatorOptions._get_program_inputs(options_dict) + if 'pubs' not in converted_options: + converted_options['pubs'] = [] + return converted_options - def assert_valid_options(self, estimator, options_to_check, options_path="", options_object=None): + def assert_valid_options(self, options_dict): """Verifies the schema validation gives the same result as attempting to set the options in the estimator""" - if options_object is None: - options = estimator.options - else: - options = options_object + converted_options = self.get_converted_options(options_dict) + error_message = None + options_valid = True + try: + self.validator.validate(converted_options) + except Exception as err: + options_valid = False + error_message = str(err) + + estimator_options_valid = True try: - for option_name, value in options_to_check.items(): - setattr(options, option_name, value) - options_dict = TestEstimatorV2Schema.get_options_dict(estimator) - print(options_dict) - self.assertTrue(self.validator.is_valid(options_dict)) - except AssertionError as err: - raise err - except Exception: - options_dict = TestEstimatorV2Schema.get_options_dict(estimator) - for option_name, value in options_to_check.items(): - dict_to_change = options_dict - for key in options_path: - if key not in dict_to_change: - dict_to_change[key] = {} - dict_to_change = dict_to_change[key] - dict_to_change[option_name] = value - self.assertFalse(self.validator.is_valid(options_dict)) - - def test_basic(self): - """Testing the bare-bones options for an estimator""" - estimator = EstimatorV2(backend=self.backend) - options = self.get_options_dict(estimator) - self.assertIsNone(self.validator.validate(options)) + EstimatorOptions(**options_dict) + except Exception as err: + estimator_options_valid = False + error_message = str(err) + + if estimator_options_valid: + self.assertTrue(options_valid, msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}") + else: + self.assertFalse(options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for EstimatorOptions it fails with the message:\n{error_message}") @ddt.data(0, 1, 2, 3, -1, 17, 3.5) def test_resilience_level(self, level): """Testing various values of the resilience level""" - estimator = EstimatorV2(backend=self.backend) - options_to_set = {'resilience_level': level} - self.assert_valid_options(estimator, options_to_set) + options = {'resilience_level': level} + self.assert_valid_options(options) @ddt.data(0, 1, 3.5) def test_seed_estimator(self, seed): """Testing various values of the seed estimator""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options'] - options_to_set = {'seed_estimator': seed} - self.assert_valid_options(estimator, options_to_set, options_path) + options = {'seed_estimator': seed} + self.assert_valid_options(options) @ddt.data(0, 1, 3.5) def test_default_precision(self, precision): """Testing various values of the default precision""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options'] - options_to_set = {'default_precision': precision} - self.assert_valid_options(estimator, options_to_set, options_path) + options = {'default_precision': precision} + self.assert_valid_options(options) @ddt.data(0, 1, 3.5, -2) def test_default_shots(self, shots): """Testing various values of the default shots""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options'] - options_to_set = {'default_shots': shots} - self.assert_valid_options(estimator, options_to_set, options_path) + options = {'default_shots': shots} + self.assert_valid_options(options) - @combine(enable=[True, False, 13, "False"], + @combine(enable=[True, False, 13], sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], extra_slack_distribution=["middle", "edges", "end", 13], scheduling_method=["alap", "asap", "lapsap", 13] ) def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribution, scheduling_method): """Testing various values of dynamical decoupling""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options', 'dynamical_decoupling'] - options_to_set = { - 'enable': enable, - 'sequence_type': sequence_type, - 'extra_slack_distribution': extra_slack_distribution, - 'scheduling_method': scheduling_method + options = { + 'dynamical_decoupling':{ + 'enable': enable, + 'sequence_type': sequence_type, + 'extra_slack_distribution': extra_slack_distribution, + 'scheduling_method': scheduling_method + } } - self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.dynamical_decoupling) + self.assert_valid_options(options) @ddt.data(0, 1, 3.5, -2) - def test_transpilation(self, optimization_level): - """Testing various values of the transpilation options""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options', 'transpilation'] - options_to_set = {'optimization_level': optimization_level} - self.assert_valid_options(estimator, options_to_set, options_path) - - @combine(measure_mitigation=[True, False, 13, "False"], - zne_mitigation=[True, False, 13, "False"], - pec_mitigation=[True, False, 13, "False"], - ) - def test_resilience(self, measure_mitigation, zne_mitigation, pec_mitigation): - """Testing various values of resilience""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options', 'resilience'] - options_to_set = { - 'measure_mitigation': measure_mitigation, - 'zne_mitigation': zne_mitigation, - 'pec_mitigation': pec_mitigation, - } - self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.resilience) + def test_optimization_level(self, optimization_level): + """Testing various values of the optimization level options""" + options = {'optimization_level': optimization_level} + self.assert_valid_options(options) @combine(num_randomizations=[0, 1, 2, True, "False"], shots_per_randomization=[0, 1, 2, True, "False", "auto"], + enable_measure_mitigation=[True, False], ) - def test_measure_noise_learning(self, num_randomizations, shots_per_randomization): + def test_measure_noise_learning(self, num_randomizations, shots_per_randomization, enable_measure_mitigation): """Testing various values of measure noise learning""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options', 'resilience', 'measure_noise_learning'] - options_to_set = { - 'num_randomizations': num_randomizations, - 'shots_per_randomization': shots_per_randomization, + options = { + 'resilience': { + 'measure_noise_learning': { + 'num_randomizations': num_randomizations, + 'shots_per_randomization': shots_per_randomization, + }, + 'measure_mitigation': enable_measure_mitigation + } } - self.assert_valid_options(estimator, options_to_set, options_path, estimator.options.resilience.measure_noise_learning) + self.assert_valid_options(options) @combine(noise_factors=[[17], [1,2], [1,4,8], [1.3, 3.2], False], extrapolator=["linear", "exponential", "double_exponential", @@ -164,15 +135,18 @@ def test_measure_noise_learning(self, num_randomizations, shots_per_randomizatio "polynomial_degree_4", "polynomial_degree_5", "polynomial_degree_6", "polynomial_degree_7", ["linear", "exponential", "polynomial_degree_3"], "false_extrapolator", 13, False, [13, "linear"] - ] + ], + enable_zne_mitigation=[True, False], ) - def test_zne_mitigation_options(self, noise_factors, extrapolator): - """Testing various values of measure noise learning""" - estimator = EstimatorV2(backend=self.backend) - options_path = ['options', 'resilience', 'zne'] - options_to_set = { - 'noise_factors': noise_factors, - 'extrapolator': extrapolator, + def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mitigation): + """Testing various values of zne mitigation""" + options = { + 'resilience': { + 'zne': { + 'noise_factors': noise_factors, + 'extrapolator': extrapolator, + }, + 'zne_mitigation': enable_zne_mitigation + } } - self.assert_valid_options(estimator, options_to_set, options_path, - estimator.options.resilience.zne) + self.assert_valid_options(options) From 5b117e3c2f072ad9fd694c6158d00e28d40e6924 Mon Sep 17 00:00:00 2001 From: gadial Date: Mon, 8 Apr 2024 16:18:40 +0300 Subject: [PATCH 32/51] Updated the schema to verify zne implies zne_mitigation=True, and measure_noise_mitigation implies measure_noise_mitigation=True --- schemas/estimator_v2_schema.json | 35 ++++++++++++++++++++++++++++++++ tests/test_primitive_schemas.py | 32 +++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 78f9e37..e0d6d39 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -397,6 +397,7 @@ } ] }, + "pec_mitigation": { "description": "Whether to turn on Probabilistic Error Cancellation error mitigation method", "type": "boolean" @@ -479,6 +480,40 @@ } } } + }, + { + "if": { + "$comment": "measure noise learning options requires measure_mitigation=True", + "properties": { + "measure_noise_learning": { + "type": "object" + } + } + }, + "then": { + "properties": { + "measure_mitigation": { + "const": true + } + } + } + }, + { + "if": { + "$comment": "zne options requires zne_mitigation=True", + "properties": { + "zne": { + "type": "object" + } + } + }, + "then": { + "properties": { + "zne_mitigation": { + "const": true + } + } + } } ] }, diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index aa1f835..b3db380 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -112,8 +112,8 @@ def test_optimization_level(self, optimization_level): options = {'optimization_level': optimization_level} self.assert_valid_options(options) - @combine(num_randomizations=[0, 1, 2, True, "False"], - shots_per_randomization=[0, 1, 2, True, "False", "auto"], + @combine(num_randomizations=[0, 1, 2, "False"], + shots_per_randomization=[0, 1, 2, "False", "auto"], enable_measure_mitigation=[True, False], ) def test_measure_noise_learning(self, num_randomizations, shots_per_randomization, enable_measure_mitigation): @@ -150,3 +150,31 @@ def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mi } } self.assert_valid_options(options) + +# options = {"resilience": {"zne": {"noise_factors": [1, 3]}}} +# #est_options = EstimatorOptions(**options) +# a = TestEstimatorV2Schema() +# a.setUp() +# print(a.get_converted_options(options)) +# a.validator.validate(a.get_converted_options(options)) +# options = {'transpilation': {'optimization_level': 0}} +# est_options = EstimatorOptions(**options) +# options = {'resilience_level': 1, "resilience": {"zne": {"noise_factors": []}}} +# res = EstimatorOptions._get_program_inputs(options) +# print(res) +# a = TestEstimatorV2Schema() +# a.setUp() +# options_dict = {'options': {'resilience': {'zne': {'noise_factors': [1.0, 4.0, 8.0], 'extrapolator': 'linear'}}}, 'version': 2, 'support_qiskit': True, 'pubs': []} +# a.validator.validate(options_dict) +# print(a.validator.is_valid(options_dict)) +# estimator = EstimatorV2(backend="ibmq_qasm_simulator") +# estimator.options.resilience.zne_mitigation = True +# estimator.options.resilience.zne.extrapolator = "linear" +# estimator.options.resilience.zne.noise_factors = [] +# print(estimator.options._get_program_inputs(asdict(estimator.options))) + +#options = {"resilience": {"zne_mitigation": True, "zne": {"noise_factors": []}}} +# options = {"resilience": {"zne": {"noise_factors": [1, 3, 5]}}} +# est_options = EstimatorOptions(**options) +# print(est_options) +# print(est_options._get_program_inputs(asdict(est_options))) \ No newline at end of file From 0b361c3c82ec7496718f322866eef2503ef867ff Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 09:57:33 +0300 Subject: [PATCH 33/51] Added pec options tests and updated the schema to require `pec_mitigation=True` if `pec` options are used --- schemas/estimator_v2_schema.json | 19 +++++++++++++- tests/test_primitive_schemas.py | 43 ++++++++++++-------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index e0d6d39..28eb59e 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -403,7 +403,7 @@ "type": "boolean" }, "pec": { - "description": "Additional probabalistic error cancellation mitigation options", + "description": "Additional probabilistic error cancellation mitigation options", "type": "object", "properties": { "max_overhead": { @@ -514,6 +514,23 @@ } } } + }, + { + "if": { + "$comment": "pec options requires pec_mitigation=True", + "properties": { + "pec": { + "type": "object" + } + } + }, + "then": { + "properties": { + "pec_mitigation": { + "const": true + } + } + } } ] }, diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index b3db380..f21afbc 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -151,30 +151,19 @@ def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mi } self.assert_valid_options(options) -# options = {"resilience": {"zne": {"noise_factors": [1, 3]}}} -# #est_options = EstimatorOptions(**options) -# a = TestEstimatorV2Schema() -# a.setUp() -# print(a.get_converted_options(options)) -# a.validator.validate(a.get_converted_options(options)) -# options = {'transpilation': {'optimization_level': 0}} -# est_options = EstimatorOptions(**options) -# options = {'resilience_level': 1, "resilience": {"zne": {"noise_factors": []}}} -# res = EstimatorOptions._get_program_inputs(options) -# print(res) -# a = TestEstimatorV2Schema() -# a.setUp() -# options_dict = {'options': {'resilience': {'zne': {'noise_factors': [1.0, 4.0, 8.0], 'extrapolator': 'linear'}}}, 'version': 2, 'support_qiskit': True, 'pubs': []} -# a.validator.validate(options_dict) -# print(a.validator.is_valid(options_dict)) -# estimator = EstimatorV2(backend="ibmq_qasm_simulator") -# estimator.options.resilience.zne_mitigation = True -# estimator.options.resilience.zne.extrapolator = "linear" -# estimator.options.resilience.zne.noise_factors = [] -# print(estimator.options._get_program_inputs(asdict(estimator.options))) - -#options = {"resilience": {"zne_mitigation": True, "zne": {"noise_factors": []}}} -# options = {"resilience": {"zne": {"noise_factors": [1, 3, 5]}}} -# est_options = EstimatorOptions(**options) -# print(est_options) -# print(est_options._get_program_inputs(asdict(est_options))) \ No newline at end of file + @combine(max_overhead=[0, 1, 18, None, "error"], + noise_gain=[0, 1, 18, "auto", None, "error"], + enable_pec_mitigation=[True, False], + ) + def test_pec_mitigation_options(self, max_overhead, noise_gain, enable_pec_mitigation): + """Testing various values of pec mitigation""" + options = { + 'resilience': { + 'pec': { + 'max_overhead': max_overhead, + 'noise_gain': noise_gain, + }, + 'pec_mitigation': enable_pec_mitigation + } + } + self.assert_valid_options(options) From 520983ba540bae36a5098fe6d432738d6d9a42af Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 10:05:43 +0300 Subject: [PATCH 34/51] Added noise learning tests --- schemas/estimator_v2_schema.json | 1 - tests/test_primitive_schemas.py | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 28eb59e..85d6c81 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -397,7 +397,6 @@ } ] }, - "pec_mitigation": { "description": "Whether to turn on Probabilistic Error Cancellation error mitigation method", "type": "boolean" diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index f21afbc..3df9fe0 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -139,7 +139,7 @@ def test_measure_noise_learning(self, num_randomizations, shots_per_randomizatio enable_zne_mitigation=[True, False], ) def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mitigation): - """Testing various values of zne mitigation""" + """Testing various values of pec mitigation""" options = { 'resilience': { 'zne': { @@ -151,6 +151,26 @@ def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mi } self.assert_valid_options(options) + @combine(max_layers_to_learn=[0, 1, 15, -3], + shots_per_randomization=[0, 1, 15, -3], + num_randomizations=[0, 1, 15, -3], + layer_pair_depths=[[0, 1, 15], 15, [0, -3]] + ) + def test_layer_noise_learning_options(self, max_layers_to_learn, shots_per_randomization, num_randomizations, layer_pair_depths): + """Testing various values of layer noise learning""" + options = { + 'resilience': { + 'layer_noise_learning': { + 'max_layers_to_learn': max_layers_to_learn, + 'shots_per_randomization': shots_per_randomization, + 'num_randomizations': num_randomizations, + 'layer_pair_depths': layer_pair_depths, + }, + } + } + self.assert_valid_options(options) + + @combine(max_overhead=[0, 1, 18, None, "error"], noise_gain=[0, 1, 18, "auto", None, "error"], enable_pec_mitigation=[True, False], From ca098086b0e42d2a7caf8d031e7abdd07dffcb12 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 10:44:38 +0300 Subject: [PATCH 35/51] Added execution and twirling tests --- tests/test_primitive_schemas.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 3df9fe0..dffc1ff 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -187,3 +187,36 @@ def test_pec_mitigation_options(self, max_overhead, noise_gain, enable_pec_mitig } } self.assert_valid_options(options) + + @combine(init_qubits=[True, False, 13], + rep_delay=[0, 13, 0.3, -5, 'error'], + ) + def test_execution_options(self, init_qubits, rep_delay): + """Testing various values of execution options""" + options = { + 'execution': { + 'init_qubits': init_qubits, + 'rep_delay': rep_delay, + } + } + self.assert_valid_options(options) + + @combine(enable_gates=[True, False, 13], + enable_measure=[True, False, 13], + num_randomizations=[0, 1, 18, -3, "auto", None, "error"], + shots_per_randomization=[0, 1, 18, -3, "auto", None, "error"], + strategy=["active", "active-circuit", "active-accum", "all", "auto", "error", 42], + ) + def test_twirling_options(self, enable_gates, enable_measure, num_randomizations, shots_per_randomization, strategy): + """Testing various values of twirling options""" + options = { + 'twirling': { + 'enable_gates': enable_gates, + 'enable_measure': enable_measure, + 'num_randomizations': num_randomizations, + 'shots_per_randomization': shots_per_randomization, + 'strategy': strategy, + } + } + self.assert_valid_options(options) + From 2cd2681432228f6e1ffc73f7ff28d2178ea2d895 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 10:55:57 +0300 Subject: [PATCH 36/51] Added Sampler tests --- tests/test_primitive_schemas.py | 80 ++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index dffc1ff..566283d 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -16,7 +16,7 @@ import ddt import jsonschema -from qiskit_ibm_runtime import EstimatorOptions +from qiskit_ibm_runtime import EstimatorOptions, SamplerOptions from tests import combine SCHEMAS_PATH = os.path.join( @@ -30,7 +30,6 @@ def setUp(self) -> None: with open(os.path.join(SCHEMAS_PATH, 'estimator_v2_schema.json'), 'r') as fd: self.estimator_schema = json.load(fd) self.validator = jsonschema.Draft202012Validator(schema=self.estimator_schema) - self.backend = "ibmq_qasm_simulator" @staticmethod def get_converted_options(options_dict): @@ -220,3 +219,80 @@ def test_twirling_options(self, enable_gates, enable_measure, num_randomizations } self.assert_valid_options(options) + +@ddt.ddt +class TestSamplerV2Schema(unittest.TestCase): + """Tests the sampler schema agrees with the format of the qiskit runtime sampler API calls""" + def setUp(self) -> None: + with open(os.path.join(SCHEMAS_PATH, 'sampler_v2_schema.json'), 'r') as fd: + self.sampler_schema = json.load(fd) + self.validator = jsonschema.Draft202012Validator(schema=self.sampler_schema) + + @staticmethod + def get_converted_options(options_dict): + """Emulate the process in `qiskit-ibm-runtime` where the EstimatorOptions + are converted to a filtered options dictionary""" + converted_options = SamplerOptions._get_program_inputs(options_dict) + if 'pubs' not in converted_options: + converted_options['pubs'] = [] + return converted_options + + def assert_valid_options(self, options_dict): + """Verifies the schema validation gives the same result as attempting + to set the options in the estimator""" + converted_options = self.get_converted_options(options_dict) + error_message = None + options_valid = True + try: + self.validator.validate(converted_options) + except Exception as err: + options_valid = False + error_message = str(err) + + sampler_options_valid = True + try: + SamplerOptions(**options_dict) + except Exception as err: + sampler_options_valid = False + error_message = str(err) + + if sampler_options_valid: + self.assertTrue(options_valid, msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}") + else: + self.assertFalse(options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for SamplerOptions it fails with the message:\n{error_message}") + + @ddt.data(0, 1, 3.5, -2) + def test_default_shots(self, shots): + """Testing various values of the default shots""" + options = {'default_shots': shots} + self.assert_valid_options(options) + + @combine(enable=[True, False, 13], + sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], + extra_slack_distribution=["middle", "edges", "end", 13], + scheduling_method=["alap", "asap", "lapsap", 13] + ) + def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribution, scheduling_method): + """Testing various values of dynamical decoupling""" + options = { + 'dynamical_decoupling': { + 'enable': enable, + 'sequence_type': sequence_type, + 'extra_slack_distribution': extra_slack_distribution, + 'scheduling_method': scheduling_method + } + } + self.assert_valid_options(options) + + @combine(init_qubits=[True, False, 13], + rep_delay=[0, 13, 0.3, -5, 'error'], + ) + def test_execution_options(self, init_qubits, rep_delay): + """Testing various values of execution options""" + options = { + 'execution': { + 'init_qubits': init_qubits, + 'rep_delay': rep_delay, + } + } + self.assert_valid_options(options) \ No newline at end of file From 5cb7635384cee3340614f0636fc6a2b5e54ba945 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 10:56:29 +0300 Subject: [PATCH 37/51] linting --- tests/test_primitive_schemas.py | 293 +++++++++++++++++++------------- 1 file changed, 179 insertions(+), 114 deletions(-) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 566283d..4afc8f4 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -20,14 +20,16 @@ from tests import combine SCHEMAS_PATH = os.path.join( - os.path.dirname(os.path.dirname(os.path.abspath(__file__))), - 'schemas') + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "schemas" +) + @ddt.ddt class TestEstimatorV2Schema(unittest.TestCase): """Tests the estimator schema agrees with the format of the qiskit runtime estimator API calls""" + def setUp(self) -> None: - with open(os.path.join(SCHEMAS_PATH, 'estimator_v2_schema.json'), 'r') as fd: + with open(os.path.join(SCHEMAS_PATH, "estimator_v2_schema.json"), "r") as fd: self.estimator_schema = json.load(fd) self.validator = jsonschema.Draft202012Validator(schema=self.estimator_schema) @@ -36,8 +38,8 @@ def get_converted_options(options_dict): """Emulate the process in `qiskit-ibm-runtime` where the EstimatorOptions are converted to a filtered options dictionary""" converted_options = EstimatorOptions._get_program_inputs(options_dict) - if 'pubs' not in converted_options: - converted_options['pubs'] = [] + if "pubs" not in converted_options: + converted_options["pubs"] = [] return converted_options def assert_valid_options(self, options_dict): @@ -60,47 +62,56 @@ def assert_valid_options(self, options_dict): error_message = str(err) if estimator_options_valid: - self.assertTrue(options_valid, msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}") + self.assertTrue( + options_valid, + msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}", + ) else: - self.assertFalse(options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for EstimatorOptions it fails with the message:\n{error_message}") + self.assertFalse( + options_valid, + msg=f"Options passed the JSON schema validation, but it should fail since for EstimatorOptions it fails with the message:\n{error_message}", + ) @ddt.data(0, 1, 2, 3, -1, 17, 3.5) def test_resilience_level(self, level): """Testing various values of the resilience level""" - options = {'resilience_level': level} + options = {"resilience_level": level} self.assert_valid_options(options) @ddt.data(0, 1, 3.5) def test_seed_estimator(self, seed): """Testing various values of the seed estimator""" - options = {'seed_estimator': seed} + options = {"seed_estimator": seed} self.assert_valid_options(options) @ddt.data(0, 1, 3.5) def test_default_precision(self, precision): """Testing various values of the default precision""" - options = {'default_precision': precision} + options = {"default_precision": precision} self.assert_valid_options(options) @ddt.data(0, 1, 3.5, -2) def test_default_shots(self, shots): """Testing various values of the default shots""" - options = {'default_shots': shots} + options = {"default_shots": shots} self.assert_valid_options(options) - @combine(enable=[True, False, 13], - sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], - extra_slack_distribution=["middle", "edges", "end", 13], - scheduling_method=["alap", "asap", "lapsap", 13] - ) - def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribution, scheduling_method): + @combine( + enable=[True, False, 13], + sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], + extra_slack_distribution=["middle", "edges", "end", 13], + scheduling_method=["alap", "asap", "lapsap", 13], + ) + def test_dynamical_decoupling( + self, enable, sequence_type, extra_slack_distribution, scheduling_method + ): """Testing various values of dynamical decoupling""" options = { - 'dynamical_decoupling':{ - 'enable': enable, - 'sequence_type': sequence_type, - 'extra_slack_distribution': extra_slack_distribution, - 'scheduling_method': scheduling_method + "dynamical_decoupling": { + "enable": enable, + "sequence_type": sequence_type, + "extra_slack_distribution": extra_slack_distribution, + "scheduling_method": scheduling_method, } } self.assert_valid_options(options) @@ -108,113 +119,156 @@ def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribut @ddt.data(0, 1, 3.5, -2) def test_optimization_level(self, optimization_level): """Testing various values of the optimization level options""" - options = {'optimization_level': optimization_level} + options = {"optimization_level": optimization_level} self.assert_valid_options(options) - @combine(num_randomizations=[0, 1, 2, "False"], - shots_per_randomization=[0, 1, 2, "False", "auto"], - enable_measure_mitigation=[True, False], - ) - def test_measure_noise_learning(self, num_randomizations, shots_per_randomization, enable_measure_mitigation): + @combine( + num_randomizations=[0, 1, 2, "False"], + shots_per_randomization=[0, 1, 2, "False", "auto"], + enable_measure_mitigation=[True, False], + ) + def test_measure_noise_learning( + self, num_randomizations, shots_per_randomization, enable_measure_mitigation + ): """Testing various values of measure noise learning""" options = { - 'resilience': { - 'measure_noise_learning': { - 'num_randomizations': num_randomizations, - 'shots_per_randomization': shots_per_randomization, + "resilience": { + "measure_noise_learning": { + "num_randomizations": num_randomizations, + "shots_per_randomization": shots_per_randomization, }, - 'measure_mitigation': enable_measure_mitigation + "measure_mitigation": enable_measure_mitigation, } } self.assert_valid_options(options) - @combine(noise_factors=[[17], [1,2], [1,4,8], [1.3, 3.2], False], - extrapolator=["linear", "exponential", "double_exponential", - "polynomial_degree_1", "polynomial_degree_2", "polynomial_degree_3", - "polynomial_degree_4", "polynomial_degree_5", "polynomial_degree_6", - "polynomial_degree_7", ["linear", "exponential", "polynomial_degree_3"], "false_extrapolator", - 13, False, [13, "linear"] - ], - enable_zne_mitigation=[True, False], - ) - def test_zne_mitigation_options(self, noise_factors, extrapolator, enable_zne_mitigation): + @combine( + noise_factors=[[17], [1, 2], [1, 4, 8], [1.3, 3.2], False], + extrapolator=[ + "linear", + "exponential", + "double_exponential", + "polynomial_degree_1", + "polynomial_degree_2", + "polynomial_degree_3", + "polynomial_degree_4", + "polynomial_degree_5", + "polynomial_degree_6", + "polynomial_degree_7", + ["linear", "exponential", "polynomial_degree_3"], + "false_extrapolator", + 13, + False, + [13, "linear"], + ], + enable_zne_mitigation=[True, False], + ) + def test_zne_mitigation_options( + self, noise_factors, extrapolator, enable_zne_mitigation + ): """Testing various values of pec mitigation""" options = { - 'resilience': { - 'zne': { - 'noise_factors': noise_factors, - 'extrapolator': extrapolator, + "resilience": { + "zne": { + "noise_factors": noise_factors, + "extrapolator": extrapolator, }, - 'zne_mitigation': enable_zne_mitigation + "zne_mitigation": enable_zne_mitigation, } } self.assert_valid_options(options) - @combine(max_layers_to_learn=[0, 1, 15, -3], - shots_per_randomization=[0, 1, 15, -3], - num_randomizations=[0, 1, 15, -3], - layer_pair_depths=[[0, 1, 15], 15, [0, -3]] - ) - def test_layer_noise_learning_options(self, max_layers_to_learn, shots_per_randomization, num_randomizations, layer_pair_depths): + @combine( + max_layers_to_learn=[0, 1, 15, -3], + shots_per_randomization=[0, 1, 15, -3], + num_randomizations=[0, 1, 15, -3], + layer_pair_depths=[[0, 1, 15], 15, [0, -3]], + ) + def test_layer_noise_learning_options( + self, + max_layers_to_learn, + shots_per_randomization, + num_randomizations, + layer_pair_depths, + ): """Testing various values of layer noise learning""" options = { - 'resilience': { - 'layer_noise_learning': { - 'max_layers_to_learn': max_layers_to_learn, - 'shots_per_randomization': shots_per_randomization, - 'num_randomizations': num_randomizations, - 'layer_pair_depths': layer_pair_depths, + "resilience": { + "layer_noise_learning": { + "max_layers_to_learn": max_layers_to_learn, + "shots_per_randomization": shots_per_randomization, + "num_randomizations": num_randomizations, + "layer_pair_depths": layer_pair_depths, }, } } self.assert_valid_options(options) - - @combine(max_overhead=[0, 1, 18, None, "error"], - noise_gain=[0, 1, 18, "auto", None, "error"], - enable_pec_mitigation=[True, False], - ) - def test_pec_mitigation_options(self, max_overhead, noise_gain, enable_pec_mitigation): + @combine( + max_overhead=[0, 1, 18, None, "error"], + noise_gain=[0, 1, 18, "auto", None, "error"], + enable_pec_mitigation=[True, False], + ) + def test_pec_mitigation_options( + self, max_overhead, noise_gain, enable_pec_mitigation + ): """Testing various values of pec mitigation""" options = { - 'resilience': { - 'pec': { - 'max_overhead': max_overhead, - 'noise_gain': noise_gain, + "resilience": { + "pec": { + "max_overhead": max_overhead, + "noise_gain": noise_gain, }, - 'pec_mitigation': enable_pec_mitigation + "pec_mitigation": enable_pec_mitigation, } } self.assert_valid_options(options) - @combine(init_qubits=[True, False, 13], - rep_delay=[0, 13, 0.3, -5, 'error'], - ) + @combine( + init_qubits=[True, False, 13], + rep_delay=[0, 13, 0.3, -5, "error"], + ) def test_execution_options(self, init_qubits, rep_delay): """Testing various values of execution options""" options = { - 'execution': { - 'init_qubits': init_qubits, - 'rep_delay': rep_delay, + "execution": { + "init_qubits": init_qubits, + "rep_delay": rep_delay, } } self.assert_valid_options(options) - @combine(enable_gates=[True, False, 13], - enable_measure=[True, False, 13], - num_randomizations=[0, 1, 18, -3, "auto", None, "error"], - shots_per_randomization=[0, 1, 18, -3, "auto", None, "error"], - strategy=["active", "active-circuit", "active-accum", "all", "auto", "error", 42], - ) - def test_twirling_options(self, enable_gates, enable_measure, num_randomizations, shots_per_randomization, strategy): + @combine( + enable_gates=[True, False, 13], + enable_measure=[True, False, 13], + num_randomizations=[0, 1, 18, -3, "auto", None, "error"], + shots_per_randomization=[0, 1, 18, -3, "auto", None, "error"], + strategy=[ + "active", + "active-circuit", + "active-accum", + "all", + "auto", + "error", + 42, + ], + ) + def test_twirling_options( + self, + enable_gates, + enable_measure, + num_randomizations, + shots_per_randomization, + strategy, + ): """Testing various values of twirling options""" options = { - 'twirling': { - 'enable_gates': enable_gates, - 'enable_measure': enable_measure, - 'num_randomizations': num_randomizations, - 'shots_per_randomization': shots_per_randomization, - 'strategy': strategy, + "twirling": { + "enable_gates": enable_gates, + "enable_measure": enable_measure, + "num_randomizations": num_randomizations, + "shots_per_randomization": shots_per_randomization, + "strategy": strategy, } } self.assert_valid_options(options) @@ -223,8 +277,9 @@ def test_twirling_options(self, enable_gates, enable_measure, num_randomizations @ddt.ddt class TestSamplerV2Schema(unittest.TestCase): """Tests the sampler schema agrees with the format of the qiskit runtime sampler API calls""" + def setUp(self) -> None: - with open(os.path.join(SCHEMAS_PATH, 'sampler_v2_schema.json'), 'r') as fd: + with open(os.path.join(SCHEMAS_PATH, "sampler_v2_schema.json"), "r") as fd: self.sampler_schema = json.load(fd) self.validator = jsonschema.Draft202012Validator(schema=self.sampler_schema) @@ -233,8 +288,8 @@ def get_converted_options(options_dict): """Emulate the process in `qiskit-ibm-runtime` where the EstimatorOptions are converted to a filtered options dictionary""" converted_options = SamplerOptions._get_program_inputs(options_dict) - if 'pubs' not in converted_options: - converted_options['pubs'] = [] + if "pubs" not in converted_options: + converted_options["pubs"] = [] return converted_options def assert_valid_options(self, options_dict): @@ -257,42 +312,52 @@ def assert_valid_options(self, options_dict): error_message = str(err) if sampler_options_valid: - self.assertTrue(options_valid, msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}") + self.assertTrue( + options_valid, + msg=f"Options should pass the JSON schema validation, but it failed with the message:\n{error_message}", + ) else: - self.assertFalse(options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for SamplerOptions it fails with the message:\n{error_message}") + self.assertFalse( + options_valid, + msg=f"Options passed the JSON schema validation, but it should fail since for SamplerOptions it fails with the message:\n{error_message}", + ) @ddt.data(0, 1, 3.5, -2) def test_default_shots(self, shots): """Testing various values of the default shots""" - options = {'default_shots': shots} + options = {"default_shots": shots} self.assert_valid_options(options) - @combine(enable=[True, False, 13], - sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], - extra_slack_distribution=["middle", "edges", "end", 13], - scheduling_method=["alap", "asap", "lapsap", 13] - ) - def test_dynamical_decoupling(self, enable, sequence_type, extra_slack_distribution, scheduling_method): + @combine( + enable=[True, False, 13], + sequence_type=["XX", "XpXm", "XY4", "ZZ", 13], + extra_slack_distribution=["middle", "edges", "end", 13], + scheduling_method=["alap", "asap", "lapsap", 13], + ) + def test_dynamical_decoupling( + self, enable, sequence_type, extra_slack_distribution, scheduling_method + ): """Testing various values of dynamical decoupling""" options = { - 'dynamical_decoupling': { - 'enable': enable, - 'sequence_type': sequence_type, - 'extra_slack_distribution': extra_slack_distribution, - 'scheduling_method': scheduling_method + "dynamical_decoupling": { + "enable": enable, + "sequence_type": sequence_type, + "extra_slack_distribution": extra_slack_distribution, + "scheduling_method": scheduling_method, } } self.assert_valid_options(options) - @combine(init_qubits=[True, False, 13], - rep_delay=[0, 13, 0.3, -5, 'error'], - ) + @combine( + init_qubits=[True, False, 13], + rep_delay=[0, 13, 0.3, -5, "error"], + ) def test_execution_options(self, init_qubits, rep_delay): """Testing various values of execution options""" options = { - 'execution': { - 'init_qubits': init_qubits, - 'rep_delay': rep_delay, + "execution": { + "init_qubits": init_qubits, + "rep_delay": rep_delay, } } - self.assert_valid_options(options) \ No newline at end of file + self.assert_valid_options(options) From 16f4322bf85f55ae523f5f334301d13e8c0a5d74 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 11:17:26 +0300 Subject: [PATCH 38/51] Schema fix: `noise_gain` is inclusive minimum --- schemas/estimator_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 85d6c81..2560f72 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -422,7 +422,7 @@ "oneOf": [ { "type": "number", - "exclusiveMinimum": 0 + "minimum": 0 }, { "enum": [ From 7387a4bd1b7e54b8e03575d6a2f24e264ee8e0fe Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 12:04:13 +0300 Subject: [PATCH 39/51] Added default shots/precision --- schemas/estimator_v2_schema.json | 4 ++++ schemas/sampler_v2_schema.json | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 2560f72..0fa3eef 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -590,6 +590,10 @@ 2 ] }, + "precision": { + "description": "Default precision level which applies to all pubs without precision", + "type": "number" + }, "version": { "description": "For EstimatorV2, version should always be 2", "enum": [2] diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 1e95e1d..0a9db0d 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -69,6 +69,10 @@ } } }, + "shots": { + "description": "Default number of shots which applies to all pubs without shots", + "type": "integer" + }, "version": { "description": "For SamplerV2, version should always be 2", "enum": [2] From 24579c4cc6d7fa98e563cb8ff415077f0170f1b2 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 23 Apr 2024 12:08:52 +0300 Subject: [PATCH 40/51] Added `support_qiskit` --- schemas/estimator_v2_schema.json | 4 ++++ schemas/sampler_v2_schema.json | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 0fa3eef..2db76ae 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -594,6 +594,10 @@ "description": "Default precision level which applies to all pubs without precision", "type": "number" }, + "support_qiskit": { + "description": "If True, returns a qiskit-style output, meant to be parsed using the runtime result decoder, or resort to returning pure JSON results (resulting in larger objects)", + "type": "bool" + }, "version": { "description": "For EstimatorV2, version should always be 2", "enum": [2] diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 0a9db0d..cf7ffdf 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -73,6 +73,10 @@ "description": "Default number of shots which applies to all pubs without shots", "type": "integer" }, + "support_qiskit": { + "description": "If True, returns a qiskit-style output, meant to be parsed using the runtime result decoder, or resort to returning pure JSON results (resulting in larger objects)", + "type": "bool" + }, "version": { "description": "For SamplerV2, version should always be 2", "enum": [2] From 7983a03a738c0f04870f680a14510fc32e70dfc2 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 24 Apr 2024 12:21:51 +0300 Subject: [PATCH 41/51] Additional data on PUBS --- schemas/estimator_v2_schema.json | 6 +++--- schemas/sampler_v2_schema.json | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 2db76ae..5bb0dd1 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -9,13 +9,13 @@ "properties": { "pubs": { "type": "array", - "description": "Circuits/Observbles/Parameters to run", + "description": "Primitive Unit Blocs of data. Each PUB is of the form (Circuit, Observables, Parameters, Precision) where the circuit and observables are required, parameters should be passed only for parametrized circuits, and precision is optional", "items": { "type": "array", "minItems": 2, "prefixItems": [ - {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, - {"description": "One or more observables.", "type": "array"}, + {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, + {"description": "One or more observables, which can be given as strings.", "type": "array"}, {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The precision for this specific pub", "type": "number"} ] diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index cf7ffdf..3faf5f5 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -9,14 +9,14 @@ "properties": { "pubs": { "type": "array", - "description": "Circuits/Parameters to run", + "description": "Primitive Unit Blocs of data. Each PUB is of the form (Circuit, Parameters, Shots) where the circuit is required, parameters should be passed only for parametrized circuits, and shots is optional", "items": { "type": "array", "minItems": 1, "prefixItems": [ - {"description": "The quantum circuit in base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, - {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, - {"description": "The numebr of shots to use in this pub", "type": "integer"} + {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, + {"description": "A dictionary of the parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, + {"description": "The number of shots to use in this pub", "type": "integer"} ] } }, From 34a6cb4e0c0db34310e3dbb81e546c83b62f2b8c Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 24 Apr 2024 12:32:29 +0300 Subject: [PATCH 42/51] Allow longer line length with flake8 --- .flake8 | 2 ++ tests/test_primitive_schemas.py | 34 +++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..79a16af --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 120 \ No newline at end of file diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 4afc8f4..3116941 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -16,6 +16,8 @@ import ddt import jsonschema +from qiskit.circuit.library import RealAmplitudes +from qiskit.primitives import StatevectorEstimator from qiskit_ibm_runtime import EstimatorOptions, SamplerOptions from tests import combine @@ -69,7 +71,8 @@ def assert_valid_options(self, options_dict): else: self.assertFalse( options_valid, - msg=f"Options passed the JSON schema validation, but it should fail since for EstimatorOptions it fails with the message:\n{error_message}", + msg=f"Options passed the JSON schema validation, but it should fail since for " + f"EstimatorOptions it fails with the message:\n{error_message}", ) @ddt.data(0, 1, 2, 3, -1, 17, 3.5) @@ -222,6 +225,7 @@ def test_pec_mitigation_options( "pec_mitigation": enable_pec_mitigation, } } + print(options) self.assert_valid_options(options) @combine( @@ -319,7 +323,8 @@ def assert_valid_options(self, options_dict): else: self.assertFalse( options_valid, - msg=f"Options passed the JSON schema validation, but it should fail since for SamplerOptions it fails with the message:\n{error_message}", + msg=f"Options passed the JSON schema validation, but it should fail since for " + f"SamplerOptions it fails with the message:\n{error_message}", ) @ddt.data(0, 1, 3.5, -2) @@ -361,3 +366,28 @@ def test_execution_options(self, init_qubits, rep_delay): } } self.assert_valid_options(options) + + +@ddt.ddt +class TestEstimatorResultV2Schema(unittest.TestCase): + """Tests the estimator result schema""" + + def setUp(self) -> None: + with open( + os.path.join(SCHEMAS_PATH, "estimator_result_v2_schema.json"), "r" + ) as fd: + self.estimator_result_schema = json.load(fd) + self.validator = jsonschema.Draft202012Validator( + schema=self.estimator_result_schema + ) + self.generate_backend_run_result() + + def generate_backend_run_result(self): + self.backend = StatevectorEstimator() + circuit = RealAmplitudes(2) + self.run_result = self.backend.run( + [(circuit, "XX", [[1, 2, 3, 4, 5, 6, 7, 8]])] + ).result() + + def test_run_result(self): + print(self.run_result) From 74e3c831a2ec2b971a03a44328dd1f35ea673934 Mon Sep 17 00:00:00 2001 From: gadial Date: Wed, 24 Apr 2024 12:33:58 +0300 Subject: [PATCH 43/51] linting --- tests/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/__init__.py b/tests/__init__.py index 157a575..e9f30e0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -15,6 +15,7 @@ import itertools from ddt import data, unpack + class Case(dict): """""" From 167a74d0360c06cdf8c24e57f9e39f67edea4102 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 25 Apr 2024 09:31:30 +0300 Subject: [PATCH 44/51] Switching to test against the `main` branch of `qiskit-ibm-runtime` --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index cf00324..6f40619 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,4 +2,4 @@ fastjsonschema jsonschema jsonschema-rs ddt -qiskit-ibm-runtime>=0.22 \ No newline at end of file +qiskit-ibm-runtime@git+ssh://git@github.com/Qiskit/qiskit-ibm-runtime.git \ No newline at end of file From ab2c1d471b5fd0027da2332a62897c3980b26c59 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 25 Apr 2024 09:34:32 +0300 Subject: [PATCH 45/51] use https instead of ssh --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 6f40619..31a298a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,4 +2,4 @@ fastjsonschema jsonschema jsonschema-rs ddt -qiskit-ibm-runtime@git+ssh://git@github.com/Qiskit/qiskit-ibm-runtime.git \ No newline at end of file +qiskit-ibm-runtime@git+https://git@github.com/Qiskit/qiskit-ibm-runtime.git \ No newline at end of file From 1441aa2414b05cb3feb53c9e63488f6ee5020468 Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 25 Apr 2024 09:57:34 +0300 Subject: [PATCH 46/51] Fixes --- schemas/estimator_v2_schema.json | 2 +- schemas/sampler_v2_schema.json | 2 +- tests/test_primitive_schemas.py | 30 ++---------------------------- 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 5bb0dd1..8e8570d 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -596,7 +596,7 @@ }, "support_qiskit": { "description": "If True, returns a qiskit-style output, meant to be parsed using the runtime result decoder, or resort to returning pure JSON results (resulting in larger objects)", - "type": "bool" + "type": "boolean" }, "version": { "description": "For EstimatorV2, version should always be 2", diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 3faf5f5..eabdafc 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -75,7 +75,7 @@ }, "support_qiskit": { "description": "If True, returns a qiskit-style output, meant to be parsed using the runtime result decoder, or resort to returning pure JSON results (resulting in larger objects)", - "type": "bool" + "type": "boolean" }, "version": { "description": "For SamplerV2, version should always be 2", diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 3116941..239a0a9 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -72,7 +72,7 @@ def assert_valid_options(self, options_dict): self.assertFalse( options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for " - f"EstimatorOptions it fails with the message:\n{error_message}", + f"EstimatorOptions it fails with the message:\n{error_message}", ) @ddt.data(0, 1, 2, 3, -1, 17, 3.5) @@ -225,7 +225,6 @@ def test_pec_mitigation_options( "pec_mitigation": enable_pec_mitigation, } } - print(options) self.assert_valid_options(options) @combine( @@ -324,7 +323,7 @@ def assert_valid_options(self, options_dict): self.assertFalse( options_valid, msg=f"Options passed the JSON schema validation, but it should fail since for " - f"SamplerOptions it fails with the message:\n{error_message}", + f"SamplerOptions it fails with the message:\n{error_message}", ) @ddt.data(0, 1, 3.5, -2) @@ -366,28 +365,3 @@ def test_execution_options(self, init_qubits, rep_delay): } } self.assert_valid_options(options) - - -@ddt.ddt -class TestEstimatorResultV2Schema(unittest.TestCase): - """Tests the estimator result schema""" - - def setUp(self) -> None: - with open( - os.path.join(SCHEMAS_PATH, "estimator_result_v2_schema.json"), "r" - ) as fd: - self.estimator_result_schema = json.load(fd) - self.validator = jsonschema.Draft202012Validator( - schema=self.estimator_result_schema - ) - self.generate_backend_run_result() - - def generate_backend_run_result(self): - self.backend = StatevectorEstimator() - circuit = RealAmplitudes(2) - self.run_result = self.backend.run( - [(circuit, "XX", [[1, 2, 3, 4, 5, 6, 7, 8]])] - ).result() - - def test_run_result(self): - print(self.run_result) From 7687e6e07a7a3f7a8a9ced8703057a30840943ae Mon Sep 17 00:00:00 2001 From: gadial Date: Thu, 25 Apr 2024 09:58:52 +0300 Subject: [PATCH 47/51] Fixes --- tests/test_primitive_schemas.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 239a0a9..55813d2 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -16,8 +16,6 @@ import ddt import jsonschema -from qiskit.circuit.library import RealAmplitudes -from qiskit.primitives import StatevectorEstimator from qiskit_ibm_runtime import EstimatorOptions, SamplerOptions from tests import combine From 7335f969c6422ef9b945455572256859ab099063 Mon Sep 17 00:00:00 2001 From: Jessie Yu Date: Mon, 20 May 2024 10:54:36 -0400 Subject: [PATCH 48/51] Fix shots --- schemas/sampler_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index eabdafc..8ba5f12 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -69,7 +69,7 @@ } } }, - "shots": { + "default_shots": { "description": "Default number of shots which applies to all pubs without shots", "type": "integer" }, From f6304e83ca29efb3c7af1cc9f6cd846e48856bb6 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 21 May 2024 10:38:21 +0300 Subject: [PATCH 49/51] Added `meas_type` to Sampler schema --- requirements-dev.txt | 2 +- schemas/sampler_v2_schema.json | 4 ++++ tests/test_primitive_schemas.py | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 31a298a..e4bff87 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,4 +2,4 @@ fastjsonschema jsonschema jsonschema-rs ddt -qiskit-ibm-runtime@git+https://git@github.com/Qiskit/qiskit-ibm-runtime.git \ No newline at end of file +qiskit-ibm-runtime>=0.23 \ No newline at end of file diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 8ba5f12..8c4fb79 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -64,6 +64,10 @@ "rep_delay": { "description": "The delay between a measurement and the subsequent quantum circuit", "type": "number" + }, + "meas_type": { + "description": "How to process and return measurement results", + "enum": ["classified", "kerneled", "avg_kerneled"] } } } diff --git a/tests/test_primitive_schemas.py b/tests/test_primitive_schemas.py index 55813d2..d1f211a 100644 --- a/tests/test_primitive_schemas.py +++ b/tests/test_primitive_schemas.py @@ -353,13 +353,15 @@ def test_dynamical_decoupling( @combine( init_qubits=[True, False, 13], rep_delay=[0, 13, 0.3, -5, "error"], + meas_type=["classified", "kerneled", "avg_kerneled", "unclassified", 42], ) - def test_execution_options(self, init_qubits, rep_delay): + def test_execution_options(self, init_qubits, rep_delay, meas_type): """Testing various values of execution options""" options = { "execution": { "init_qubits": init_qubits, "rep_delay": rep_delay, + "meas_type": meas_type, } } self.assert_valid_options(options) From b9f86871958419765806ec4e41c2810d75351fc5 Mon Sep 17 00:00:00 2001 From: gadial Date: Tue, 21 May 2024 10:55:55 +0300 Subject: [PATCH 50/51] QuantumCircuit can be either object or string --- requirements-dev.txt | 2 +- schemas/estimator_v2_schema.json | 2 +- schemas/sampler_v2_schema.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e4bff87..31a298a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,4 +2,4 @@ fastjsonschema jsonschema jsonschema-rs ddt -qiskit-ibm-runtime>=0.23 \ No newline at end of file +qiskit-ibm-runtime@git+https://git@github.com/Qiskit/qiskit-ibm-runtime.git \ No newline at end of file diff --git a/schemas/estimator_v2_schema.json b/schemas/estimator_v2_schema.json index 8e8570d..5a938b9 100644 --- a/schemas/estimator_v2_schema.json +++ b/schemas/estimator_v2_schema.json @@ -14,7 +14,7 @@ "type": "array", "minItems": 2, "prefixItems": [ - {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, + {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": ["object", "string"]}, {"description": "One or more observables, which can be given as strings.", "type": "array"}, {"description": "The parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The precision for this specific pub", "type": "number"} diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 8c4fb79..8c704d0 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -14,7 +14,7 @@ "type": "array", "minItems": 1, "prefixItems": [ - {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": "object"}, + {"description": "The quantum circuit in QASM string or base64-encoded QPY format. See https://docs.quantum.ibm.com/api/qiskit/qpy for more details on QPY.", "type": ["object", "string"]}, {"description": "A dictionary of the parameter values. The keys are the names of the parameters, and the values are the actual parameter values.", "type": "object"}, {"description": "The number of shots to use in this pub", "type": "integer"} ] From bbf4bd940922483eaae9d6eaa6053faa679339e7 Mon Sep 17 00:00:00 2001 From: Jessie Yu Date: Tue, 21 May 2024 08:53:54 -0400 Subject: [PATCH 51/51] Change back to shots --- schemas/sampler_v2_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/sampler_v2_schema.json b/schemas/sampler_v2_schema.json index 8c704d0..6c1b466 100644 --- a/schemas/sampler_v2_schema.json +++ b/schemas/sampler_v2_schema.json @@ -73,7 +73,7 @@ } } }, - "default_shots": { + "shots": { "description": "Default number of shots which applies to all pubs without shots", "type": "integer" },