Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix QASM examples #1993

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/guides/primitive-input-output.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"id": "04b9204f-f058-433b-89f9-05df14645e27",
"metadata": {},
"source": [
"<span id=\"pub-overview\"></span>\n",
"## Overview of PUBs\n",
"\n",
"When invoking a primitive's [`run()`](../api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2#run) method, the main argument that is required is a `list` of one or more tuples -- one for each circuit being executed by the primitive. Each of these tuples is considered a PUB, and the required elements of each tuple in the list depends on the the primitive used. The data provided to these tuples can also be arranged in a variety of shapes to provide flexibility in a workload through broadcasting -- the rules of which are described in a [following section](#broadcasting-rules).\n",
Expand Down
169 changes: 155 additions & 14 deletions docs/guides/primitives-rest-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ url = 'https://api.quantum-computing.ibm.com/runtime/jobs'
headers = {
'Content-Type': 'application/json',
'x-access-token':auth_id,
'x-qx-client-application': 'qiskit-version-2/0.39.2/'+'your_application' # specifying the application you might be running from. For an actual Integration project, this option is invaluable to know where jobs are coming from. At this time the "qiskit-version-2/0.39.2/" string is a necessary prefix.
# Replace <your_application> with the name of your application. This is useful to understand
# where jobs are coming from. Note that the prefix "qiskit-version-2/0.39.2/" is necessary.
'x-qx-client-application': f'qiskit-version-2/0.39.2/<your_application>',
}
job_input = {
'program_id': 'estimator',
Expand Down Expand Up @@ -290,7 +292,7 @@ Find details on how to initialize your account, view available backends, and inv
You need at least one circuit as the input to the Sampler primitive.


Define a QASM quantum circuit:
Define a QASM quantum circuit:

```python
qasm_string='''
Expand All @@ -302,7 +304,7 @@ x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''
'''
```


Expand All @@ -328,11 +330,11 @@ headers = {
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"backend": backend,
"hub": "hub1",
"group": "group1",
"project": "project1",
"start_session": "False", # set to False if you just need to run a single job.
"start_session": "False", # set to False if you just need to run a single job.
"params": {
"pubs": [[resulting_qasm],[resulting_qasm,None,500]], # primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"version": 2 # this defines the version of the Qiskit Runtime Primitive to use, c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
Expand Down Expand Up @@ -384,9 +386,9 @@ Output
Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model.

The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the `resilience_level` option when submitting your job.
Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods.
Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods.

The following examples demonstrate the default options for dynamical decoupling and twirling. Find more options and further details in the [Error mitigation and suppression techniques](./error-mitigation-and-suppression-techniques) topic.
The following examples demonstrate the default options for dynamical decoupling and twirling. Find more options and further details in the [Error mitigation and suppression techniques](./error-mitigation-and-suppression-techniques) topic.

<Tabs>

Expand All @@ -403,16 +405,16 @@ headers = {
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"backend": backend,
"hub": "hub1",
"group": "group1",
"project": "project1",
"start_session": "False", # set to False if you just need to run a single job.
"start_session": "False", # set to False if you just need to run a single job.
"params": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"version": 2, # this defines the version of the Qiskit Runtime Primitive to use, c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"options": {
"dynamical_decoupling": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
Expand Down Expand Up @@ -446,17 +448,17 @@ headers = {
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"backend": backend,
"hub": "hub1",
"group": "group1",
"project": "project1",
"start_session": "False", # set to False if you just need to run a single job.
"start_session": "False", # set to False if you just need to run a single job.
"params": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"version": 2, # this defines the version of the Qiskit Runtime Primitive to use, c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"options": {
"twirling": {
"enable_gates": True,
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": "auto",
"shots_per_randomization": "auto",
Expand All @@ -479,6 +481,144 @@ else:
</TabItem>
</Tabs>

<span id="start-sampler-parms"></span>
## Sampler primitive with REST API and parameterized circuits

### 1. Initialize the account

Because Qiskit Runtime is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.

Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](./setup-channel#set-up-to-use-ibm-quantum-platform-with-rest-api).

### 2. Define parameters

```python
import requests
import qiskit_ibm_runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.qasm3 import dumps
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit import transpile

service = QiskitRuntimeService(channel='ibm_quantum')
beckykd marked this conversation as resolved.
Show resolved Hide resolved
backend = service.backend("<your selected backend>")

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)

theta = Parameter('theta')
phi = Parameter('phi')
parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary
```


### 3. Create a quantum circuit and add parameterized gates

```python
qc = QuantumCircuit(2)

# Add parameterized gates
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)
qc.measure_all()

# Draw the original circuit
qc.draw('mpl')

# Get an ISA circuit
isa_circuit = pm.run(qc)
```

### 4. Generate QASM 3 code

```python
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
```

### 5. Run the quantum circuit using Sampler V2 API


<Admonition type="note">
The jobs below use Qiskit Runtime V2 [primitives](/guides/primitives). Both [`SamplerV2`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.SamplerV2) and [`EstimatorV2`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.EstimatorV2) take one or more [primitive unified blocs (PUBs)](/guides/primitive-input-output#pub-overview) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.
beckykd marked this conversation as resolved.
Show resolved Hide resolved
</Admonition>


```python
import requests

url = 'https://api.quantum-computing.ibm.com/runtime/jobs'
headers = {
'Content-Type': 'application/json',
'"Authorization": f"Bearer xxxxxxx",
'x-qx-client-application': 'qiskit-version-2/<version>/'+'<your_application>' # This is set by the client making the request. You can use it to include information such as the package version used. For an integration project, this option is helpful in understanding where jobs are coming from. The prefix 'qiskit-version-2/<version>/' is required.
}

job_input = {
'program_id': 'sampler',
"backend": backend,
"hub": "hub1",
"group": "group1",
"project": "project1",
"start_session": "False", # set to False if you just need to run a single job.
"params": {
# Choose one option: direct parameter transfer or through a dictionary
#"pubs": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"pubs": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
"version": 2 # this defines the version of the Qiskit Runtime Primitive to use, c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print(f"Job created: {response.text}")
else:
print(f"Error: {response.status_code}")
```

```python
print(response.text)
```


### 6. Check job status and get results

Next, pass the `job_id` to the API:

```python
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
```

Output
beckykd marked this conversation as resolved.
Show resolved Hide resolved

```text
{'status': 'Completed'}
```

Get job results:
beckykd marked this conversation as resolved.
Show resolved Hide resolved

```python
response_result = requests.get(f"{url}/{job_id}/results", headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])
```

Output
beckykd marked this conversation as resolved.
Show resolved Hide resolved

```text
['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']
```

## Next steps

<Admonition type="tip" title="Recommendations">
Expand All @@ -488,4 +628,5 @@ else:
- Read [Migrate to V2 primitives](/migration-guides/v2-primitives).
- Practice with primitives by working through the [Cost function lesson](https://learning.quantum.ibm.com/course/variational-algorithm-design/cost-functions#primitives) in IBM Quantum Learning.
- Learn how to transpile locally in the [Transpile](./transpile) section.
- [Migrate to the Qiskit Runtime V2 primitives.](/migration-guides/v2-primitives)
</Admonition>
6 changes: 3 additions & 3 deletions docs/guides/transpile-rest-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: How to transpile quantum circuits using REST APIs.

The process of rewriting a given input circuit to match the topology of a specific quantum device, and optimizing the circuit instructions for execution on noisy quantum QPUs, is known as [transpilation](./transpile).

You have two transpilation options:
You have two transpilation options:

* Transpile [locally via Qiskit](./defaults-and-configuration-options) before generating the QASM string.

Expand All @@ -21,7 +21,7 @@ You have two transpilation options:
[Transpilation is necessary](https://docs.quantum.ibm.com/announcements/product-updates/2024-02-14-qiskit-runtime-primitives-update) prior to submitting a circuit to IBM&reg; QPUs.
</Admonition>

The steps in this topic describe how to transpile a given QASM circuit and obtain results using the Cloud Transpiler REST API, and include suggestions on how to submit the transpiled quantum circuit to IBM compute resources.
The steps in this topic describe how to transpile a given QASM circuit and obtain results using the Cloud Transpiler REST API, and include suggestions on how to submit the transpiled quantum circuit to IBM compute resources. For an example that uses parameterized input, see [Sampler primitive with REST API and parameterized circuits.](/guides/primitives-rest-api#start-sampler-parms)

## Query the Qiskit Transpiler Service

Expand Down Expand Up @@ -94,7 +94,7 @@ resp = requests.post(


<Admonition type="note">
Since there might be cases where it’s more effective not to use AI-enhanced passes, you can set the `ai` parameter to `ai="auto"` to enable the QPU to decide automatically whether to apply the standard Qiskit heuristic passes or the new AI-powered passes, based on the particulars of your circuit.
Since there might be cases where it’s more effective not to use AI-enhanced passes, you can set the `ai` parameter to `ai="auto"` to enable the QPU to decide automatically whether to apply the standard Qiskit heuristic passes or the new AI-powered passes, based on the particulars of your circuit.
</Admonition>

## Request results based on the `task_id`
Expand Down
Loading