\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "79d463c4-81c6-49b2-9817-1bed7cb98517",
+ "metadata": {},
+ "source": [
+ "To view the backends you have access to, you can use the `QiskitRuntimeService.backends()` method. Let's check your backend list:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6fc011cc-77df-461a-bc99-93ffd22eb672",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "service.backends()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0f8ba878-89b0-458e-8854-034cb7c7b433",
+ "metadata": {},
+ "source": [
+ "The `QiskitRuntimeService.backend()` method (note that this is singular: backend) takes the name of the backend as the input parameter and returns an IBMBackend instance representing that particular backend. The following code will select `ibmq_qasm_simulator` and save it as a `backend_sim`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f6bf1f98-b992-47fc-85ea-ff534b7977eb",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "backend_sim = service.backend(\"ibmq_qasm_simulator\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "231e0279-e1bf-43c0-b77b-01a77b5dbd5e",
+ "metadata": {},
+ "source": [
+ "You can also filter the available backends by their properties. For more general filters, you can make advanced functions using a lambda function. Refer to the [API documentation](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#backends) for more details.\n",
+ "\n",
+ "As shown here, we will filter least busy real backend and save it to `backend`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "67109b11-1157-4356-9e24-5a63bb513795",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "backend = service.least_busy(simulator=False, operational=True)\n",
+ "backend"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0155d3e0-93f0-4950-bbe7-dfd64a99e26a",
+ "metadata": {},
+ "source": [
+ "### Create a toy circuit\n",
+ "\n",
+ "Now, let's create a random circuit by using `qiskit.circuit.random.random_circuit` with 5 qubits with depth=3 with measurement. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e7610fbe-d2b0-4475-9c7c-e6e0ec751d66",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.random import random_circuit\n",
+ " \n",
+ "circ = random_circuit(5, 3, measure=True)\n",
+ "circ.draw(output='mpl', style='iqp')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bc4dae59-a927-4efb-b030-510505418763",
+ "metadata": {},
+ "source": [
+ "### Execute using a quantum primitive function\n",
+ "\n",
+ "Quantum computers can produce random results, so you'll often want to collect a sample of the outputs by running the circuit many times. You can use the `Sampler` class to get measured data from a quantum Computer.. `Sampler` is one of our two [primitives](https://docs.quantum.ibm.com/run/primitives-get-started); the other is `Estimator`, which estimates the value of observable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a72b8e00-89e1-492c-860c-775f2e72d68d",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "from qiskit_ibm_runtime import Sampler, Options\n",
+ " \n",
+ "options = Options()\n",
+ "options.resilience_level = 1\n",
+ "options.optimization_level = 3\n",
+ " \n",
+ "# Create an Estimator object\n",
+ "sampler = Sampler(backend_sim, options=options)\n",
+ " \n",
+ "# Submit the circuit to Estimator\n",
+ "job = sampler.run(circ, shots = 10000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5c2996ff-e30b-4e55-82f9-5fe6a7411508",
+ "metadata": {},
+ "source": [
+ "You can print the job's id and status by using the job instance. Run below cell to check both."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7e873269-7312-4f7c-a4af-cf87c8def5eb",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "jobid = job.job_id()\n",
+ "print(f\">>> Job ID: {job.job_id()}\")\n",
+ "print(f\">>> Job Status: {job.status()}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "db17081f-a469-4a38-bdec-5500e968a642",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Note: \n",
+ " Jobs submitted by using the qiskit_ibm_runtime provider are not visible in the right side panel of qBraid Lab
\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "23e66477-79dc-4e24-a964-07a486203348",
+ "metadata": {},
+ "source": [
+ "### Retrieve job results at a later time\n",
+ "\n",
+ "You can call service.job(\\) to retrieve a job you previously submitted. If you don’t have the job ID, or if you want to retrieve multiple jobs at once; including jobs from retired systems, call service.jobs() with optional filters instead. See [QiskitRuntimeService.jobs](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#jobs) for details.\n",
+ "\n",
+ "As shown here, we will retrieve the job result and save it as a `retrieve_job` to see the result."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7c477078-67be-46d8-8378-962f6a9b9dea",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "retrieve_job = service.job(jobid)\n",
+ "result = retrieve_job.result()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "945f9635-a576-47cd-94b4-78fd7fadea0f",
+ "metadata": {},
+ "source": [
+ "Now we will plot the results. \n",
+ "\n",
+ "As sampler returns quasi probability of measurement, let's use `plot_distribution` with a binary expression. See [SamplerResult document](https://docs.quantum.ibm.com/api/qiskit/qiskit.primitives.SamplerResult) for more information."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d0590e58-9eea-4589-a774-6652c37d2e9f",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "from qiskit.visualization import plot_distribution\n",
+ "\n",
+ "plot_distribution(result.quasi_dists[0].binary_probabilities())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "03ec980a-f294-4498-82cf-cb4c35a1f3b6",
+ "metadata": {},
+ "source": [
+ "## 2. Using qBraid SDK"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "de67207f-3dd5-499e-bb72-0ad0100b3228",
+ "metadata": {},
+ "source": [
+ "By following [this lab demo](https://github.com/qBraid/qbraid-lab-demo/blob/045c7a8fbdcae66a7e64533dd9fe0e981dc02cf4/qbraid_sdk/ibm_batch_jobs_grovers.ipynb#L4) provided by qBraid, you can also use qbraid sdk to submit your ibm job and check job status. The following show how to do that.\n",
+ "\n",
+ "First, check the qbraid version."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5854118c-2d37-497e-934f-784bdc431b21",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "import qbraid\n",
+ "\n",
+ "qbraid.__version__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7d67c858-1ab0-4e46-bf47-f77ccd8f3e87",
+ "metadata": {},
+ "source": [
+ "Now import essential libraries and save your ibm api token as an environment variable. Then, set-up your `QiskitProvider` with that token."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1029c085-6e9f-4f56-b525-8d0b294d6dd4",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "\n",
+ "from qbraid import device_wrapper, job_wrapper, get_jobs\n",
+ "from qbraid.providers import QuantumJob\n",
+ "from qbraid.providers.exceptions import JobStateError\n",
+ "from qbraid.providers.ibm import QiskitBackend, QiskitJob, QiskitProvider\n",
+ "import os\n",
+ "\n",
+ "os.environ['QISKIT_IBM_TOKEN'] = ''\n",
+ "ibmq_token = os.getenv(\"QISKIT_IBM_TOKEN\")\n",
+ "provider = QiskitProvider(qiskit_ibm_token=ibmq_token)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aee25386-eb1c-4f11-ab63-38be584e73bc",
+ "metadata": {},
+ "source": [
+ "You can also see the device list, accessible with your token."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a79c8520-01f7-4146-860f-996b60cf914c",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "provider.get_devices()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a1fb6069-3a00-4250-ad6f-11851ef9089f",
+ "metadata": {},
+ "source": [
+ "`qbraid.providers.ibm` also supports useful filtering by `get_devices()`. You can quickly find the least busy backend by using `ibm_least_busy_gpu()`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6f562ceb-72d9-4be4-8e8b-15690286c558",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "#ibm_device = provider.ibm_least_busy_qpu() #return least busy backend of provider\n",
+ "#ibm_device = provider.get_devices(operational=True, simulator=False) #return backend list which is now operate and not a simulator\n",
+ "ibm_device = provider.get_device(\"ibm_kyoto\") #return backend by name\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "545c1b43-9679-4dd6-ad6c-3dc7a48833df",
+ "metadata": {},
+ "source": [
+ "To send the quantum circuit to the backend and check the job status in the right sidebar of qBraid Quantum lab, wrap the ibm backend with `device_wrapper`. If you insert the backend, which does not appear in the right sidebar panel's \"device\" section, this code will return an error."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "086710ef-5cac-4fe3-95f0-d071c8321cea",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "#qbraid_ibm_device = device_wrapper(ibm_device) #you and add device called by provider as well\n",
+ "qbraid_ibm_device = device_wrapper(\"ibm_kyoto\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "953be90a-d983-444d-8d1f-4ebe9cd9f0e8",
+ "metadata": {},
+ "source": [
+ "To send a quantum circuit, you can simply call `wrapped_device.run(circuit, options)`. See [API document](https://docs.qbraid.com/en/stable/sdk/devices.html#device-wrapper) for more information."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5c92dd6f-c82f-46a5-bf80-07bdfc2f254d",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "qbraid_ibm_job = qbraid_ibm_device.run(circ, shots=20000)#works if backend is at Devices list. Error if I try to use premium backend"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "52c2510a-2a69-4624-aede-56237b76fe53",
+ "metadata": {},
+ "source": [
+ "Shortly afterwards you should see your submitted job in the right side panel. If you cannot see your job, click the circulation icon at the top to refresh or select `All` for Provider.\n",
+ "\n",
+ "Also, you can check your job status by using `job_wrapper(job_id).` Please note that the `job_id` for `job_wrapper` must be a qBraidID, which you can get by adding `.id` to your job."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0bb09636-cfbf-480d-aa53-734cd5a11c07",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "job = job_wrapper(qbraid_ibm_job.id)\n",
+ "job.status()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2c65961f-540e-43dc-b318-c57d86e31751",
+ "metadata": {},
+ "source": [
+ "You can use the `get_jobs` function to a return a list of your previously submitted quantum jobs, along with the status of each."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3523429e-3341-4a57-80e3-2ad2fb9d3871",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "get_jobs()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4dedeb3d-a03c-4b70-b9f9-a7a7000eb045",
+ "metadata": {},
+ "source": [
+ "This `qBraidID` can be used to reinstantiate a qBraid QuantumJob object at any time, and even in a separate program, with no loss of information."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "848add3e-1059-4726-be73-855fb8a7adad",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "job = job_wrapper(\"\")\n",
+ "job.status()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2ceac5e2-6738-473a-b993-cd3cf6da2e19",
+ "metadata": {},
+ "source": [
+ "After the job has completed, we’ll gather the result, print the measurement counts, and plot a histogram of the count by using `qbraid.visualization.plot_histogram`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3d39b177-e2a5-41d4-8752-a946cb475f7a",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "ibm_result = job.result()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc1bfa7a-b16e-4b71-b949-662f54a6c141",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "from qbraid.visualization import plot_histogram, plot_distribution\n",
+ "\n",
+ "plot_histogram(ibm_result.measurement_counts())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b1cb7df6-d68d-4273-b243-98b79f759f11",
+ "metadata": {},
+ "source": [
+ "Also, you can plot a histogram of a probability with `plot_distribution`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "50af7aa6-bd20-4224-9a94-e447768d869d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plot_distribution(ibm_result.measurement_counts())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6a0395af-a533-41e8-9852-d7af847def13",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "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.9.0"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/qbraid_sdk/img/ibm_api_token.png b/qbraid_sdk/img/ibm_api_token.png
new file mode 100644
index 0000000..b040d93
Binary files /dev/null and b/qbraid_sdk/img/ibm_api_token.png differ