{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 量子启发式算法GPU后端使用教程\n", "\n", "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_notebook.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.7.0rc1/mindquantum/zh_cn/case_library/mindspore_qaia_gpu_tutorial.ipynb) \n", "[![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_download_code.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.7.0rc1/mindquantum/zh_cn/case_library/mindspore_qaia_gpu_tutorial.py) \n", "[![在Gitee上查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.7.0rc1/resource/_static/logo_source.svg)](https://gitee.com/mindspore/docs/blob/r2.7.0rc1/docs/mindquantum/docs/source_zh_cn/case_library/qaia_gpu_tutorial.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "本篇教程将从下面五点进行说明:\n", "\n", "- 检查系统环境,保证GPU显卡可用。\n", "- 介绍MindQuantum和量子启发式算法。\n", "- 介绍量子启发式算法GPU后端支持的精度类型,提供样例代码。\n", "- 使用量子启发式算法GPU后端求解最大割问题。\n", "- 对比量子启发式算法在CPU和GPU后端上的性能差异" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 检查系统环境\n", "\n", "在使用量子启发式算法GPU后端来求解问题前,需要确保系统环境已经安装GPU显卡和CUDA环境,并且显卡可用:\n", "\n", "- GPU显卡:推荐系统安装NVIDIA英伟达显卡\n", "- CUDA环境:建议安装CUDA 11及以上版本" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tue Jun 10 14:49:58 2025 \n", "+---------------------------------------------------------------------------------------+\n", "| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |\n", "|-----------------------------------------+----------------------+----------------------+\n", "| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |\n", "| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |\n", "| | | MIG M. |\n", "|=========================================+======================+======================|\n", "| 0 Tesla V100S-PCIE-32GB On | 00000000:92:00.0 Off | 0 |\n", "| N/A 43C P0 39W / 250W | 410MiB / 32768MiB | 0% Default |\n", "| | | N/A |\n", "+-----------------------------------------+----------------------+----------------------+\n", " \n", "+---------------------------------------------------------------------------------------+\n", "| Processes: |\n", "| GPU GI CI PID Type Process name GPU Memory |\n", "| ID ID Usage |\n", "|=======================================================================================|\n", "+---------------------------------------------------------------------------------------+\n" ] } ], "source": [ "# 输出系统显卡型号、数量、驱动版本和CUDA版本\n", "!nvidia-smi" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 检查GPU显卡是否可用\n", "import torch\n", "\n", "torch.cuda.is_available()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## MindQuantum\n", "\n", "量子启发式算法是一类基于**量子力学原理**的计算方法衍生或启发的经典力学方法,旨在利用量子力学的独特性质(叠加态、量子纠缠和量子并行性)来改进传统算法的性能。\n", "\n", "常见的**量子启发式算法**包括:\n", "\n", "- ASB(Adiabatic Simulated bifurcation/绝热模拟分叉算法)\n", "- BSB(Ballistic Simulated bifurcation/弹道模拟分叉算法)\n", "- DSB(Discrete Simulated bifurcation/离散模拟分叉算法)\n", "- SimCIM(Simulated Coherent Ising Machine/模拟相干伊辛机算法)\n", "- LQA(Local Quantum Annealing/局部量子退火算法)\n", "\n", "**MindQuantum**是基于昇思MindSpore开源深度学习平台开发的新一代通用量子计算框架,聚焦于NISQ阶段的算法实现与落地。结合HiQ高性能量子计算模拟器和昇思MindSpore并行自动微分能力,提供极简的开发模式和极致的性能体验。\n", "\n", "MindQuantum已经[集成量子启发式算法模块](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.11/algorithm/mindquantum.algorithm.qaia.html),并提供**CPU、GPU、NUP/昇腾**版本,适配多种硬件设备,并提供极致性能。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 量子启发式算法GPU后端\n", "\n", "量子启发式算法[支持后端](https://www.mindspore.cn/mindquantum/docs/zh-CN/r0.11/algorithm/qaia/mindquantum.algorithm.qaia.QAIA.html#mindquantum.algorithm.qaia.QAIA):\n", "\n", "- backend (str) - 计算后端和精度:'cpu-float32'、'gpu-float32'、'gpu-float16'、'gpu-int8' 或 'npu-float32',默认值: 'cpu-float32'。\n", "- GPU后端提供3种数据精度:float32、float16和int8,低精度int8可以大幅提升计算速度,但是会小概率导致准确度丢失。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Cut: tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], device='cuda:0')\n", "Energy: tensor([-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.], device='cuda:0')\n" ] } ], "source": [ "# 样例代码\n", "from scipy.sparse import coo_matrix\n", "from mindquantum.algorithm.qaia import BSB\n", "\n", "# 矩阵[[0,-1],[-1,0]]\n", "J = coo_matrix(([-1, -1], ([0, 1], [1, 0])), shape=(2, 2))\n", "solver = BSB(J, batch_size=10, backend=\"gpu-float32\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "energy = solver.calc_energy()\n", "\n", "print(f\"Cut: {cut}\\nEnergy: {energy}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 使用量子启发式算法求解最大割问题" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# 导入需要的Python模块\n", "from mindquantum.algorithm.qaia import BSB\n", "import numpy as np\n", "import pandas as pd\n", "from scipy.sparse import coo_matrix" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 数据准备\n", "# 下载数据,无向图数据集来源于GSet\n", "import requests\n", "\n", "graph_file = \"https://web.stanford.edu/~yyye/yyye/Gset/G22\"\n", "\n", "# 使用requests库中的get方法发送HTTP请求,将url的响应结果存入变量,再以二进制写入模式打开文件写入本地\n", "response = requests.get(graph_file)\n", "open(\"G22\", \"wb\").write(response.content)\n", "\n", "\n", "# 如果上述-下载图集的代码执行,报错TimeoutError,说明是网络问题\n", "# 可以手动点击网址 https://web.stanford.edu/~yyye/yyye/Gset/G22,下载数据,保存在本地,与该教程同级目录" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# 数据处理\n", "def read_gset(filename, negate=True):\n", " # 读取图表\n", " graph = pd.read_csv(filename, sep=\" \")\n", " # 节点的数量\n", " n_v = int(graph.columns[0])\n", " # 边的数量\n", " n_e = int(graph.columns[1])\n", "\n", " # 如果节点和边不匹配,会抛出错误\n", " assert n_e == graph.shape[0], \"The number of edges is not matched\"\n", "\n", " # 将读取的数据转换为一个COO矩阵(Coordinate List Format),并返回一个稀疏矩阵\n", " G = coo_matrix(\n", " (\n", " np.concatenate([graph.iloc[:, -1], graph.iloc[:, -1]]),\n", " (\n", " np.concatenate([graph.iloc[:, 0] - 1, graph.iloc[:, 1] - 1]),\n", " np.concatenate([graph.iloc[:, 1] - 1, graph.iloc[:, 0] - 1]),\n", " ),\n", " ),\n", " shape=(n_v, n_v),\n", " )\n", " if negate:\n", " G = -G\n", "\n", " return G\n", "\n", "\n", "G = read_gset(\"./G22\")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MAXCut is : 13333.0\n" ] } ], "source": [ "solver = BSB(G, batch_size=100, n_iter=1000, backend=\"gpu-float32\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "\n", "print(f\"MAXCut is : {max(cut)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 性能对比\n", "\n", "对比BSB算法在CPU和GPU后端上求解最大割问题的性能差异" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "start_time = time.time()\n", "solver = BSB(G, batch_size=100, n_iter=1000, backend=\"cpu-float32\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "cpu_time = time.time() - start_time\n", "\n", "start_time = time.time()\n", "solver = BSB(G, batch_size=100, n_iter=1000, backend=\"gpu-float32\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "gpu_fp32_time = time.time() - start_time\n", "\n", "start_time = time.time()\n", "solver = BSB(G, batch_size=100, n_iter=1000, backend=\"gpu-float16\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "gpu_fp16_time = time.time() - start_time\n", "\n", "start_time = time.time()\n", "solver = BSB(G, batch_size=100, n_iter=1000, backend=\"gpu-int8\")\n", "solver.update()\n", "cut = solver.calc_cut()\n", "gpu_fp8_time = time.time() - start_time" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+8AAAK9CAYAAABVS11tAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABvx0lEQVR4nO3dd3QU1f/G8WfTy6YQEpJgIAkEqSIIooD0JoamIkWkC2hQQKWJhaIIgggqRVE6UYoUAaU3aQoKkSrSiwZBIAlFSJvfH36zP5YkkEBCRvN+nbPnkJm7dz6zd4fk2bkzazEMwxAAAAAAADAth7wuAAAAAAAA3BrhHQAAAAAAkyO8AwAAAABgcoR3AAAAAABMjvAOAAAAAIDJEd4BAAAAADA5wjsAAAAAACZHeAcAAAAAwOQI7wAAAAAAmBzhHQDyQHJysvr3768iRYrIwcFBLVq0yOuS8C83ffp0WSwWHT9+PK9L+dcaMmSILBaL3bLMjtXLly/r+eefV1BQkCwWi/r06XPvC84Hateurdq1a+d1GbcUFhamTp065XUZAPIBwjuAXLNv3z4999xzuu++++Tq6qrChQvrueee0/79+2/5vIkTJ8piseiRRx7JtI3FYtFLL72U4boDBw7IYrHIzc1NcXFxWa437Q/3tIeHh4fKlCmjN998UwkJCVnuJyumTp2q0aNHq2XLlpoxY4ZeeeWVHO0/v1q0aJEaN24sf39/ubi4qHDhwmrVqpXWrVuX16VB0vnz59WvXz+VLFlSbm5u8vPzU6NGjbRs2bIc31bahxlpDzc3NxUuXFiNGjXSxx9/rEuXLmWpn8yO1ffee0/Tp0/Xiy++qFmzZql9+/Y5vg855csvv9S4ceOy3D4sLExNmjTJcN2GDRtksVj09ddf51B1+cetfm/djWPHjumll17S/fffLw8PD9vvrp49e2r37t12bdeuXasuXbrY2hYrVkzPP/+8YmNj7dpdvXpVEyZMUMOGDRUcHCwvLy9VrFhRkyZNUkpKSo7vA4CsccrrAgD8Ny1cuFBt27aVn5+funbtqvDwcB0/flxTpkzR119/rblz56p58+YZPjc6OlphYWHavn27Dh8+rIiIiGxte/bs2QoKCtLFixf19ddf6/nnn8/W8ydNmiSr1arLly9r1apVGj58uNatW6ctW7akOyt3p9atW6f77rtPY8eOzZH+8jvDMNSlSxdNnz5dFStW1KuvvqqgoCDFxsZq0aJFqlevnrZs2aJq1arldam5pn379mrTpo1cXV3zupQMHTx4UPXq1dO5c+fUuXNnVa5cWXFxcYqOjlbTpk3Vt29fjR49Ose3O2zYMIWHhyspKUlnzpzRhg0b1KdPH3344YdasmSJypcvb2v75ptvauDAgXbPz+xYXbdunR599FENHjw4x2vOaV9++aX27t3L7ID/oGXLlql169ZycnJSu3bt9OCDD8rBwUG//vqrFi5cqEmTJunYsWMKDQ2VJA0YMEAXLlzQM888oxIlSujo0aMaP368li1bppiYGAUFBUmSjh49qpdffln16tXTq6++Km9vb61cuVJRUVH64YcfNGPGjLzcbSD/MgAghx0+fNjw8PAwSpUqZZw9e9Zu3blz54xSpUoZVqvVOHr0aLrnHj161JBkLFy40AgICDCGDBmS4TYkGT179ky3PDU11QgLCzNeffVV48knnzRq166d5boHDx5sSDLOnTtnt/ypp54yJBlbt27Ncl8ZSU1NNa5evWoYhmHUqVPHKFu27F31d6OUlBTj77//zrH+/m1Gjx5tSDL69OljpKampls/c+ZM48cff8yDynLf5cuX87qE20pMTDTKlStneHh4GD/88IPduuTkZKN169aGJGPOnDk5ts1p06YZkowdO3akW7d27VrD3d3dCA0NtR2TmcnsWA0PDzciIyNzrN7cPIYjIyON0NDQLLcPDQ3NdN/Wr19vSDLmz5+fI7Xd7v1bq1Yto1atWjmyrTt1uxpDQ0ONjh073rafzH5v3anDhw8bnp6eRunSpY0//vgj3fqkpCTjo48+Mk6ePGlbtnHjRiMlJcWu3caNGw1JxhtvvGFbdu7cOWPv3r3p+uzcubMhyTh06FCO7QeArGPaPIAcN3r0aF29elWTJ09WQECA3Tp/f3999tlnunz5coZn2aKjo1WgQAFFRkaqZcuWio6Ozta2t2zZouPHj6tNmzZq06aNvv/+e50+ffqu9qdu3bqS/pmaKEmpqakaN26cypYtKzc3NwUGBqpHjx66ePGi3fPSpp6uXLlSlStXlru7uz777DNZLBatX79e+/bts03p3bBhgyTpypUreu2111SkSBG5urqqZMmS+uCDD2QYhl3fadMvo6OjVbZsWbm6umrFihW2qcKbN29Wr169FBAQIF9fX/Xo0UOJiYmKi4tThw4dVKBAARUoUED9+/dP1/cHH3ygatWqqWDBgnJ3d1elSpUynCKbVsPixYtVrlw5ubq6qmzZslqxYkW6tr///ru6du2qwoULy9XVVeHh4XrxxReVmJhoaxMXF6c+ffrY9j0iIkLvv/++UlNTbzk+f//9t0aMGKFSpUrpgw8+yHB2RPv27VWlShXbz0ePHtUzzzwjPz8/eXh46NFHH9W3335r95y06cHz5s3T0KFDdd9998nLy0stW7ZUfHy8rl+/rj59+qhQoUKyWq3q3Lmzrl+/nuk4pU0Vr1Spkr7//nu7didOnFBUVJRKliwpd3d3FSxYUM8880y669fTxnfjxo2KiopSoUKFFBISYrfuxuf89NNPatSokfz9/eXu7q7w8HB16dLFrs/svueyMt43W7Bggfbu3auBAwemuxzG0dFRn332mXx9fTVkyJAMX//hw4crJCREbm5uqlevng4fPnzbbd5K3bp19dZbb+nEiROaPXu2bfmN17wfP34802PVYrHo2LFj+vbbb23L017369eva/DgwYqIiJCrq6uKFCmi/v373/K9ceMxLP1zvHTp0kWBgYG213nq1Kl2z8/q61O7dm19++23OnHihK3WsLCwu3r9bpYT719Jmjx5sooXLy53d3dVqVJFmzZtsnu+YRjy9/fXq6++aluWmpoqX19fOTo62l0m9f7778vJyUmXL1+WJO3evVudOnVSsWLF5ObmpqCgIHXp0kXnz5+320bae2D//v169tlnVaBAAT322GO27b/77rsKCQmRh4eH6tSpo3379t3x63a37/FRo0bpypUrmjZtmoKDg9Otd3JyUq9evVSkSBHbspo1a8rBwf7P/5o1a8rPz08HDhywLfP391fZsmXT9fnkk09Kkl1bAPcO0+YB5LilS5cqLCxMNWrUyHB9zZo1FRYWpqVLl2rixIl266Kjo/XUU0/JxcVFbdu21aRJk7Rjxw49/PDDWdp2dHS0ihcvrocffljlypWTh4eHvvrqK/Xr1++O9+fIkSOSpIIFC0qSevTooenTp6tz587q1auXjh07pvHjx2vXrl3asmWLnJ2dbc89ePCg2rZtqx49eqhbt24KCQnRrFmzNHz4cF2+fFkjRoyQJJUuXVqGYahZs2Zav369unbtqgoVKmjlypXq16+ffv/99wyn7c6bN08vvfSS/P39FRYWppiYGEnSyy+/rKCgIA0dOlQ//PCDJk+eLF9fX23dulVFixbVe++9p++++06jR49WuXLl1KFDB1u/H330kZo1a6Z27dopMTFRc+bM0TPPPKNly5YpMjLSrobNmzdr4cKFioqKkpeXlz7++GM9/fTTOnnypO31+uOPP1SlShXFxcWpe/fuKlWqlH7//Xd9/fXXunr1qlxcXHT16lXVqlVLv//+u3r06KGiRYtq69atev311xUbG3vL63U3b96sCxcuqE+fPnJ0dLzteP7555+qVq2arl69ql69eqlgwYKaMWOGmjVrpq+//tr2x2maESNGyN3dXQMHDtThw4f1ySefyNnZWQ4ODrp48aKGDBmiH374QdOnT1d4eLjefvttu+dv3LhRc+fOVa9eveTq6qqJEyfq8ccf1/bt21WuXDlJ0o4dO7R161a1adNGISEhOn78uCZNmqTatWtr//798vDwsOszKipKAQEBevvtt3XlypUM9/Ps2bNq2LChAgICNHDgQPn6+ur48eNauHChrU1233NZGe+MLF26VJLs3mc38vHxUfPmzTVjxox0l8qMHDlSDg4O6tu3r+Lj4zVq1Ci1a9dOP/74Y6bby4r27dtr0KBBWrVqlbp165ZufUBAQKbH6qxZs/TKK68oJCREr732mq19amqqmjVrps2bN6t79+4qXbq09uzZo7Fjx+q3337T4sWL7baR0TH8559/6tFHH7WF+4CAAC1fvlxdu3ZVQkJCuqnvt3t93njjDcXHx+v06dO28bRarbd9fZKSkvTXX3+lWx4fH59uWU68f6dMmaIePXqoWrVq6tOnj44ePapmzZrJz8/PFj4tFouqV69u9+HX7t27FR8fLwcHB23ZssX2f9SmTZtUsWJF276uXr1aR48eVefOnRUUFKR9+/Zp8uTJ2rdvn3744Yd0H/qlTSt/7733bB9kvf3223r33Xf1xBNP6IknntDOnTvVsGFDuw8h78SdvseXLVumiIiIW94fJisuX76sy5cvy9/f/7Ztz5w5I0lZagsgF+TdSX8A/0VxcXGGJKN58+a3bNesWTNDkpGQkGBb9tNPPxmSjNWrVxuG8c8085CQEKN3797pnq8Mph8mJiYaBQsWtJv69+yzzxoPPvhglmpPmzZ/8OBB49y5c8axY8eMzz77zHB1dTUCAwONK1euGJs2bTIkGdHR0XbPXbFiRbrloaGhhiRjxYoV6bZVq1atdFNxFy9ebEgy3n33XbvlLVu2NCwWi3H48GG7/XdwcDD27dtn1zZtqnCjRo3spo9XrVrVsFgsxgsvvGBblpycbISEhKSbknrzNOK0Kc9169a1Wy7JcHFxsavrl19+MSQZn3zyiW1Zhw4dDAcHhwynL6fV+M477xienp7Gb7/9Zrd+4MCBhqOjo920z5t99NFHhiRj0aJFmba5UZ8+fQxJxqZNm2zLLl26ZISHhxthYWG2KaVp04PLlStnJCYm2tq2bdvWsFgsRuPGje36rVq1arqpyZIMScZPP/1kW3bixAnDzc3NePLJJ23LMpq6vW3bNkOSMXPmTNuytPF97LHHjOTkZLv2aeuOHTtmGIZhLFq0KNNp42my+57LynhnpEKFCoaPj88t23z44YeGJGPJkiWGYfz/61+6dGnj+vXrtnZp471nz55b9nerafNpfHx8jIoVK9p+Tvs/4EYZHauGkfHU8lmzZhkODg527y3DMIxPP/3UkGRs2bLFtiyzY7hr165GcHCw8ddff9ktb9OmjeHj42N7r2Tn9bmTafNp793MHjdOm7/b929iYqJRqFAho0KFCnb7MnnyZEOS3f9Ro0ePNhwdHW2/Oz7++GMjNDTUqFKlijFgwADDMP65BMHX19d45ZVXblnjV199ZUgyvv/+e9uytPdA27Zt7dqePXvWcHFxMSIjI+3+bx00aJAh6Y6mzd/Nezw+Pt6QZLRo0SLduosXLxrnzp2zPW53acg777xjSDLWrl17y3bXr183ypQpY4SHhxtJSUm3bAsgdzBtHkCOSruDs5eX1y3bpa2/8Y7P0dHRCgwMVJ06dST9c5aldevWmjNnTpbubrt8+XKdP39ebdu2tS1r27atfvnll2xNbSxZsqQCAgIUHh6uHj16KCIiQt9++608PDw0f/58+fj4qEGDBvrrr79sj0qVKslqtWr9+vV2fYWHh6tRo0ZZ2u53330nR0dH9erVy275a6+9JsMwtHz5crvltWrVUpkyZTLsq2vXrnZnkh555BEZhqGuXbvaljk6Oqpy5co6evSo3XPd3d1t/7548aLi4+NVo0YN7dy5M9126tevr+LFi9t+Ll++vLy9vW19pqamavHixWratKkqV66c7vlpNc6fP181atRQgQIF7F7X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q379+mnJkiVq0qSJOnXqpEqVKunKlSvas2ePvv76ax0/fvyWX03Ur18/7du3T2PGjNH69evVsmVLBQUF6cyZM1q8eLG2b99uu8HVwIED9dVXX6lx48bq1auX/Pz8NGPGDB07dkwLFizI8T9Qy5Urp0aNGtl9VZwkDR061NamSZMmmjVrlnx8fFSmTBlt27ZNa9asueXXr93OjBkzNHHiRD355JMqXry4Ll26pM8//1ze3t62a1bv1XvOxcVFX3/9terVq6fHHntMnTt3VuXKlRUXF6cvv/xSO3fu1GuvvaY2bdrkyPZutHz5cv36669KTk7Wn3/+qXXr1mn16tUKDQ3VkiVL5ObmlmPbat++vebNm6cXXnhB69evV/Xq1ZWSkqJff/1V8+bN08qVKzO8ceONRo4cqfXr1+uRRx5Rt27dVKZMGV24cEE7d+7UmjVrdOHChWzXValSJc2dO1evvvqqHn74YVmtVjVt2vROdzOdu33/Ojs7691331WPHj1Ut25dtW7dWseOHdO0adPSXfMu/XMTSCcnJx08eFDdu3e3La9Zs6YmTZokSXbh3dvbWzVr1tSoUaOUlJSk++67T6tWrbK7v8rtBAQEqG/fvhoxYoSaNGmiJ554Qrt27dLy5cvz7GvTSpQooS+//FJt27ZVyZIl1a5dOz344IMyDEPHjh3Tl19+KQcHB4WEhNie065dO23fvl1dunTRgQMH7L6v3Wq12i49OnHihJo1ayaLxaKWLVtq/vz5dtsuX758uks4AOQ+wjuAXPH0009r586dGjFihL744gudPXtWqampcnNz088//2x3djM6Olpubm5q0KBBhn05ODgoMjJS0dHROn/+fLo/COfMmaPU1NRb/jHatGlTLViwQMuXL8/0Q4Ks+vTTT1WpUiV99tlnGjRokJycnBQWFqbnnntO1atXv+N+HRwctGTJEr399tuaO3eupk2bprCwMI0ePdr2XdK5rW7dupoyZYpGjhypPn36KDw8XO+//76OHz9+x+H9vvvu048//qi33npL0dHRSkhI0H333afGjRvbvv/Zw8NDGzdu1Hvvvaf58+dr5syZ8vb21v3336+hQ4emu+P0zRwcHDRz5kw1b95ckydP1gcffKCEhAQFBATY/mivWrWqJCkwMFBbt27VgAEDbDe4Kl++vJYuXZrue+xzQq1atVS1alUN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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# 绘制水平条形图,表示不同后端的计算时间\n", "plt.figure(figsize=(12, 8))\n", "plt.barh(0.6, gpu_fp8_time, height=0.1, label=\"GPU-Int8\", color=\"salmon\")\n", "plt.barh(0.4, gpu_fp16_time, height=0.1, label=\"GPU-Float16\", color=\"red\")\n", "plt.barh(0.2, gpu_fp32_time, height=0.1, label=\"GPU-Float32\", color=\"brown\")\n", "plt.barh(0, cpu_time, height=0.1, label=\"CPU-Float32\", color=\"royalblue\")\n", "\n", "plt.title(\"QAIA Performance Comparison On Different Hardware In G22\")\n", "plt.xlabel(\"Time(seconds)\")\n", "plt.ylabel(\"QAIA Algorithm\")\n", "plt.yticks((0.3,), (\"BSB\",))\n", "\n", "plt.grid(True, axis=\"x\", linestyle=\"-\", alpha=0.8)\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", " \n", " \n", "\n", "\n", "
SoftwareVersion
mindquantum0.10.1
scipy1.11.3
numpy1.26.1
SystemInfo
Python3.10.13
OSLinux x86_64
Memory810.22 GB
CPU Max Thread96
DateTue Jun 10 14:55:10 2025
\n" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.utils.show_info import InfoTable\n", "\n", "InfoTable(\"mindquantum\", \"scipy\", \"numpy\")" ] } ], "metadata": { "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "mindspore" }, "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.8.17" } }, "nbformat": 4, "nbformat_minor": 4 }