qiskit-documentation/docs/guides/primitives-rest-api.ipynb

1055 lines
39 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "0998165a-381f-4561-a79a-bf584aed9687",
"metadata": {},
"source": [
"{/* cspell:ignore IIZII, XIZZZ, accum */}\n",
"\n",
"# Primitives with REST API"
]
},
{
"cell_type": "markdown",
"id": "da948b6b-2ead-4359-aed4-b824e43ccbfb",
"metadata": {
"tags": [
"version-info"
]
},
"source": []
},
{
"cell_type": "markdown",
"id": "3d9ef591-91fd-4a49-a065-5e2cda4d41be",
"metadata": {},
"source": [
"<LegacyContent>\n",
"<Admonition type=\"note\">\n",
"This documentation is relevant to IBM Quantum&reg; Platform Classic. If you need the newer version, go to the new [IBM Quantum Platform documentation.](https://quantum.cloud.ibm.com/docs/guides/primitives-rest-api)\n",
"</Admonition>\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"<Admonition type=\"note\">\n",
"This documentation is relevant to the new IBM Quantum&reg; Platform. If you need the previous version, return to the [IBM Quantum Platform Classic documentation.](https://docs.quantum.ibm.com/guides/primitives-rest-api)\n",
"</Admonition>\n",
"</CloudContent>\n",
"\n",
"The steps in this topic describe how to run and configure primitive workloads with REST API, and demonstrate how to invoke them in any program of your choice.\n",
"\n",
"<Admonition type=\"note\">\n",
" This documentation utilizes the Python `requests` module to demonstrate the Qiskit Runtime REST API. However, this workflow can be executed using any language or framework that supports working with REST APIs. Refer to the [API reference documentation](/docs/api/runtime/tags/jobs) for details.\n",
"</Admonition>\n",
"\n",
"<span id=\"start-estimator\"></span>\n",
"## Estimator primitive with REST API\n",
"\n",
"### 1. Initialize the account\n",
"\n",
"Because Qiskit Runtime Estimator is a managed service, you first need to initialize your account. You can then select the device you want to use to calculate the expectation value.\n",
"<LegacyContent>\n",
"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).\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](./cloud-setup#set-up-to-use-ibm-quantum-platform-with-rest-api).\n",
"</CloudContent>\n",
"### 2. Create a QASM circuit\n",
"\n",
"You need at least one circuit as the input to the Estimator primitive.\n",
"\n",
"Define a QASM quantum circuit. For example:\n",
"\n",
"```python\n",
"qasm_string='''\n",
"OPENQASM 3;\n",
"include \"stdgates.inc\";\n",
"qreg q[2];\n",
"creg c[2];\n",
"x q[0];\n",
"cx q[0], q[1];\n",
"c[0] = measure q[0];\n",
"c[1] = measure q[1];\n",
"'''\n",
"```\n",
"\n",
"The following code snippets assume that the `qasm_string` has been transpiled to a new string `resulting_qasm`. Find detailed instructions on how to use the Qiskit Transpiler Service API in this [topic](./transpile-rest-api).\n",
"\n",
"### 3. Run the quantum circuit using the Estimator V2 API\n",
"\n",
"\n",
"<Admonition type=\"note\">\n",
" The following jobs use [Qiskit Runtime V2 primitives](/docs/migration-guides/v2-primitives). Both `SamplerV2` and `EstimatorV2` take one or more primitive unified blocs (PUBs) 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.\n",
"</Admonition>\n",
"\n",
"<LegacyContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each. c.f. https://docs.quantum.ibm.com/migration-guides/v2-primitives\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"</LegacyContent>\n",
"\n",
"\n",
"<CloudContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"</CloudContent>\n",
"\n",
"\n",
"### 4. Check job status and get results\n",
"\n",
"Next, pass the `job_id` to the API:\n",
"\n",
"```python\n",
"response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)\n",
"response_status_singlejob.json().get('state')\n",
"```\n",
"Output\n",
"\n",
"```text\n",
">>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad\n",
">>> Job Status: JobStatus.RUNNING\n",
"```\n",
"\n",
"Get job results:\n",
"```python\n",
"response_result= requests.get(url+'/'+job_id+'/results', headers=headers)\n",
"\n",
"res_dict=response_result.json()\n",
"\n",
"estimator_result=res_dict['results']\n",
"print(estimator_result)\n",
"```\n",
"Output\n",
"```text\n",
"[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]\n",
"```\n",
"\n",
"### 5. Work with Runtime options\n",
"\n",
"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.\n",
"\n",
"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.\n",
"\n",
"The following examples demonstrate the default options for dynamical decoupling, twirling, and TREX + ZNE. Find more options and further details in the [Error mitigation and suppression techniques](./error-mitigation-and-suppression-techniques) topic.\n",
"\n",
"<LegacyContent>\n",
"<Tabs>\n",
"\n",
" <TabItem value=\"TREX + ZNE\" label=\"TREX + ZNE\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]],\n",
" \"options\": {\n",
" \"resilience\": {\n",
" \"measure_mitigation\": True,\n",
" \"zne_mitigation\": True,\n",
" \"zne\": {\n",
" \"extrapolator\":[\"exponential\", \"linear\"],\n",
" \"noise_factors\":[1, 3, 5],\n",
" },\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Dynamical Decoupling\" label=\"Dynamical Decoupling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
" \"options\": {\n",
" \"dynamical_decoupling\": {\n",
" \"enable\": True,\n",
" \"sequence_type\": 'XpXm',\n",
" \"extra_slack_distribution\": 'middle',\n",
" \"scheduling_method\": 'alap',\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Twirling\" label=\"Twirling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each.\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
" \"options\": {\n",
" \"twirling\": {\n",
" \"enable_gates\": True,\n",
" \"enable_measure\": True,\n",
" \"num_randomizations\": \"auto\",\n",
" \"shots_per_randomization\": \"auto\",\n",
" \"strategy\": \"active-accum\",\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
" </TabItem>\n",
"</Tabs>\n",
"</LegacyContent>\n",
"\n",
"<CloudContent>\n",
"<Tabs>\n",
"\n",
" <TabItem value=\"TREX + ZNE\" label=\"TREX + ZNE\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"BACKEND_NAME\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
" \"options\": {\n",
" \"resilience\": {\n",
" \"measure_mitigation\": True,\n",
" \"zne_mitigation\": True,\n",
" \"zne\": {\n",
" \"extrapolator\":[\"exponential\", \"linear\"],\n",
" \"noise_factors\":[1, 3, 5],\n",
" },\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Dynamical Decoupling\" label=\"Dynamical Decoupling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"BACKEND_NAME\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
" \"options\": {\n",
" \"dynamical_decoupling\": {\n",
" \"enable\": True,\n",
" \"sequence_type\": 'XpXm',\n",
" \"extra_slack_distribution\": 'middle',\n",
" \"scheduling_method\": 'alap',\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Twirling\" label=\"Twirling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"BACKEND_NAME\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'estimator',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [ #primitive unified blocs (PUBs) containing one circuit each\n",
" [resulting_qasm, # QASM circuit\n",
" {\"IIZII\": 1, \"XIZZZ\": 2.3}, # Observable\n",
" None # parameter values\n",
" ]]\n",
" \"options\": {\n",
" \"twirling\": {\n",
" \"enable_gates\": True,\n",
" \"enable_measure\": True,\n",
" \"num_randomizations\": \"auto\",\n",
" \"shots_per_randomization\": \"auto\",\n",
" \"strategy\": \"active-accum\",\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
"\n",
" </TabItem>\n",
"</Tabs>\n",
"</CloudContent>\n",
"\n",
"\n",
"<span id=\"start-sampler\"></span>\n",
"## Sampler primitive with REST API\n",
"\n",
"### 1. Initialize the account\n",
"\n",
"Because Qiskit Runtime Sampler 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.\n",
"\n",
"<LegacyContent>\n",
"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).\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](./cloud-setup#set-up-to-use-ibm-quantum-platform-with-rest-api).\n",
"</CloudContent>\n",
"\n",
"### 2. Create a QASM circuit\n",
"\n",
"You need at least one circuit as the input to the Sampler primitive.\n",
"\n",
"\n",
"Define a QASM quantum circuit:\n",
"\n",
"```python\n",
"qasm_string='''\n",
"OPENQASM 3;\n",
"include \"stdgates.inc\";\n",
"qreg q[2];\n",
"creg c[2];\n",
"x q[0];\n",
"cx q[0], q[1];\n",
"c[0] = measure q[0];\n",
"c[1] = measure q[1];\n",
"'''\n",
"```\n",
"\n",
"\n",
"The code snippets given below assume that the `qasm_string` has been transpiled to a new string `resulting_qasm`. Find detailed instructions on how to use the Qiskit Transpiler Service API in this [topic](./transpile-rest-api).\n",
"\n",
"\n",
"### 3. Run the quantum circuit using Sampler V2 API\n",
"\n",
"\n",
"<Admonition type=\"note\">\n",
" The jobs below use [Qiskit Runtime V2 primitives](/docs/migration-guides/v2-primitives). Both `SamplerV2` and `EstimatorV2` take one or more primitive unified blocs (PUBs) 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.\n",
"</Admonition>\n",
"\n",
"<LegacyContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each.\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"</LegacyContent>\n",
"\n",
"<CloudContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each.\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"</CloudContent>\n",
"\n",
"\n",
"### 4. Check job status and get results\n",
"\n",
"Next, pass the `job_id` to the API:\n",
"\n",
"```python\n",
"response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)\n",
"response_status_singlejob.json().get('state')\n",
"```\n",
"Output\n",
"\n",
"```text\n",
">>> Job ID: 58223448-5100-4dec-a47a-942fb30edced\n",
">>> Job Status: JobStatus.RUNNING\n",
"```\n",
"\n",
"Get job results:\n",
"```python\n",
"response_result= requests.get(url+'/'+job_id+'/results', headers=headers)\n",
"\n",
"res_dict=response_result.json()\n",
"\n",
"# Get results for the first PUB\n",
"counts=res_dict['results'][0]['data']['c']['samples']\n",
"\n",
"print(counts[:20])\n",
"```\n",
"Output\n",
"```text\n",
"['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']\n",
"```\n",
"\n",
"### 5. Work with Runtime options\n",
"\n",
"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.\n",
"\n",
"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.\n",
"Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods.\n",
"\n",
"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.\n",
"\n",
"<LegacyContent>\n",
"<Tabs>\n",
"\n",
" <TabItem value=\"Dynamical Decoupling\" label=\"Dynamical Decoupling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"options\": {\n",
" \"dynamical_decoupling\": {\n",
" \"enable\": True,\n",
" \"sequence_type\": 'XpXm',\n",
" \"extra_slack_distribution\": 'middle',\n",
" \"scheduling_method\": 'alap',\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Twirling\" label=\"Twirling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm]] # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"options\": {\n",
" \"twirling\": {\n",
" \"enable_gates\": True,\n",
" \"enable_measure\": True,\n",
" \"num_randomizations\": \"auto\",\n",
" \"shots_per_randomization\": \"auto\",\n",
" \"strategy\": \"active-accum\",\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
"\n",
" </TabItem>\n",
"</Tabs>\n",
"</LegacyContent>\n",
"\n",
"<CloudContent>\n",
"<Tabs>\n",
"\n",
" <TabItem value=\"Dynamical Decoupling\" label=\"Dynamical Decoupling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"options\": {\n",
" \"dynamical_decoupling\": {\n",
" \"enable\": True,\n",
" \"sequence_type\": 'XpXm',\n",
" \"extra_slack_distribution\": 'middle',\n",
" \"scheduling_method\": 'alap',\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
" </TabItem>\n",
"\n",
" <TabItem value=\"Twirling\" label=\"Twirling\">\n",
"\n",
" ```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" \"pubs\": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"options\": {\n",
" \"twirling\": {\n",
" \"enable_gates\": True,\n",
" \"enable_measure\": True,\n",
" \"num_randomizations\": \"auto\",\n",
" \"shots_per_randomization\": \"auto\",\n",
" \"strategy\": \"active-accum\",\n",
" },\n",
" },\n",
" }\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(\"Job created:\",response.text)\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
"\n",
" </TabItem>\n",
"</Tabs>\n",
"</CloudContent>\n",
"\n",
"<span id=\"start-sampler-parms\"></span>\n",
"## Sampler primitive with REST API and parameterized circuits\n",
"\n",
"### 1. Initialize the account\n",
"\n",
"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.\n",
"\n",
"<LegacyContent>\n",
"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).\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"Find details on how to initialize your account, view available backends, and invalidate tokens in this [topic](./cloud-setup#set-up-to-use-ibm-quantum-platform-with-rest-api).\n",
"</CloudContent>\n",
"\n",
"### 2. Define parameters\n",
"\n",
"```python\n",
"import requests\n",
"import qiskit_ibm_runtime\n",
"from qiskit_ibm_runtime import QiskitRuntimeService\n",
"from qiskit.transpiler import generate_preset_pass_manager\n",
"from qiskit.qasm3 import dumps\n",
"from qiskit import QuantumCircuit\n",
"from qiskit.circuit import Parameter\n",
"from qiskit import transpile\n",
"\n",
"service = QiskitRuntimeService(channel='ibm_quantum')\n",
"backend = service.backend(\"<your selected backend>\")\n",
"\n",
"pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
"\n",
"theta = Parameter('theta')\n",
"phi = Parameter('phi')\n",
"parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary\n",
"```\n",
"\n",
"\n",
"### 3. Create a quantum circuit and add parameterized gates\n",
"\n",
"```python\n",
"qc = QuantumCircuit(2)\n",
"\n",
"# Add parameterized gates\n",
"qc.rx(theta, 0)\n",
"qc.ry(phi, 1)\n",
"qc.cx(0, 1)\n",
"qc.measure_all()\n",
"\n",
"# Draw the original circuit\n",
"qc.draw('mpl')\n",
"\n",
"# Get an ISA circuit\n",
"isa_circuit = pm.run(qc)\n",
"```\n",
"\n",
"### 4. Generate QASM 3 code\n",
"\n",
"```python\n",
"qasm_str = dumps(isa_circuit)\n",
"print(\"Generated QASM 3 code:\")\n",
"print(qasm_str)\n",
"```\n",
"\n",
"### 5. Run the quantum circuit using Sampler V2 API\n",
"\n",
"\n",
"<Admonition type=\"note\">\n",
" The following jobs use Qiskit Runtime V2 [primitives](/docs/guides/primitives). Both [`SamplerV2`](/docs/api/qiskit-ibm-runtime/sampler-v2) and [`EstimatorV2`](/docs/api/qiskit-ibm-runtime/estimator-v2) take one or more [primitive unified blocs (PUBs)](/docs/guides/primitive-input-output#pubs) 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.\n",
"</Admonition>\n",
"\n",
"<LegacyContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://api.quantum-computing.ibm.com/runtime/jobs'\n",
"auth_id = \"Bearer <YOUR_API_TOKEN>\"\n",
"backend = '<BACKEND_NAME>'\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id\n",
" }\n",
"\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"hub\": \"hub1\",\n",
" \"group\": \"group1\",\n",
" \"project\": \"project1\",\n",
" \"params\": {\n",
" # Choose one option: direct parameter transfer or through a dictionary\n",
" #\"pubs\": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"pubs\": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(f\"Job created: {response.text}\")\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
"```python\n",
"print(response.text)\n",
"```\n",
"</LegacyContent>\n",
"\n",
"<CloudContent>\n",
"```python\n",
"import requests\n",
"\n",
"url = 'https://quantum.cloud.ibm.com/v1/jobs'\n",
"auth_id = \"Bearer <YOUR_BEARER_TOKEN>\"\n",
"crn = \"<SERVICE-CRN>\"\n",
"backend = \"<BACKEND_NAME>\"\n",
"\n",
"headers = {\n",
" 'Content-Type': 'application/json',\n",
" 'Authorization':auth_id,\n",
" 'Service-CRN': crn\n",
" }\n",
"\n",
"job_input = {\n",
" 'program_id': 'sampler',\n",
" \"backend\": backend,\n",
" \"params\": {\n",
" # Choose one option: direct parameter transfer or through a dictionary\n",
" #\"pubs\": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
" \"pubs\": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.\n",
"}}\n",
"\n",
"response = requests.post(url, headers=headers, json=job_input)\n",
"\n",
"if response.status_code == 200:\n",
" job_id = response.json().get('id')\n",
" print(f\"Job created: {response.text}\")\n",
"else:\n",
" print(f\"Error: {response.status_code}\")\n",
"```\n",
"\n",
"```python\n",
"print(response.text)\n",
"```\n",
"</CloudContent>\n",
"\n",
"### 6. Check job status and get results\n",
"\n",
"Next, pass the `job_id` to the API:\n",
"\n",
"```python\n",
"response_status_singlejob = requests.get(f\"{url}/{job_id}\", headers=headers)\n",
"response_status_singlejob.json().get('state')\n",
"```\n",
"\n",
"Output\n",
"\n",
"```text\n",
"{'status': 'Completed'}\n",
"```\n",
"\n",
"Get job results:\n",
"\n",
"```python\n",
"response_result = requests.get(f\"{url}/{job_id}/results\", headers=headers)\n",
"\n",
"res_dict=response_result.json()\n",
"\n",
"# Get results for the first PUB\n",
"counts=res_dict['results'][0]['data']['c']['samples']\n",
"\n",
"print(counts[:20])\n",
"```\n",
"\n",
"Output\n",
"\n",
"```text\n",
"['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']\n",
"```\n",
"\n",
"## Next steps\n",
"<LegacyContent>\n",
"<Admonition type=\"tip\" title=\"Recommendations\">\n",
" - There are several ways to run workloads, depending on your needs: job mode, session mode and batch mode. Learn how to work with session mode and batch mode in the [execution modes topic](./execution-modes-rest-api).\n",
" - Learn how to [initialize your account](./setup-channel#set-up-to-use-ibm-quantum-platform-with-rest-api) with REST API.\n",
" - Learn how to [transpile circuits using REST API](./transpile-rest-api).\n",
" - Read [Migrate to V2 primitives](/docs/migration-guides/v2-primitives).\n",
" - 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.\n",
" - Learn how to transpile locally in the [Transpile](./transpile) section.\n",
" - [Migrate to the Qiskit Runtime V2 primitives.](/docs/migration-guides/v2-primitives)\n",
"</Admonition>\n",
"</LegacyContent>\n",
"<CloudContent>\n",
"<Admonition type=\"tip\" title=\"Recommendations\">\n",
" - There are several ways to run workloads, depending on your needs: job mode, session mode, and batch mode. Learn how to work with session mode and batch mode in the [execution modes topic](/docs/guides/execution-modes-rest-api). Note that Open Plan users cannot submit session jobs.\n",
" - Learn how to [initialize your account](./cloud-setup#set-up-to-use-ibm-quantum-platform-with-rest-api) with REST API.\n",
" - Learn how to [transpile circuits using REST API](./transpile-rest-api).\n",
" - Read [Migrate to V2 primitives](/docs/migration-guides/v2-primitives).\n",
" - 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.\n",
" - Learn how to transpile locally in the [Transpile](./transpile) section.\n",
" - [Migrate to the Qiskit Runtime V2 primitives.](/docs/migration-guides/v2-primitives)\n",
"</Admonition>\n",
"</CloudContent>"
]
}
],
"metadata": {
"description": "How to use the Sampler and Estimator primitives with Qiskit Runtime REST API.",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3"
},
"title": "Primitives with REST API"
},
"nbformat": 4,
"nbformat_minor": 4
}