技術背景
該文章一方面從量子線路的打印着手,介紹了一個簡單的python量子線路工程。同時基於這個簡單的小工程,我們順帶的介紹了python的API文檔自動化生成工具Sphinx的基本使用方法。
量子線路背景知識
在前面幾篇博客中,有介紹過使用開源量子計算編程框架ProjectQ進行量子線路的繪制,會給我們輸出一個tex格式的線路圖,在文章中可以直接使用。關於量子線路與量子邏輯門操作,在這篇博客中有比較初步的介紹。而本文章中所創建的工程,是直接在cmd窗口里面打印輸出字符串形式的量子線路,同樣的,在量子計算資源估計和量子線路工程中,可以產生一定的作用。
自動化文檔生成的方案
對於一個比較優雅的python開源項目來說,一份簡介的文檔是必不可少的。一般一個python項目的文檔有兩部分組成:一部分是用markdown撰寫的使用說明文檔,其宗旨在於概述的介紹整個項目的重點內容,以及可能包含少部分的使用示例。這部分的文檔可以先用markdown寫,然后通過一些開源工具,如mkdocs等轉換成read_the_docs格式的文檔。read_the_docs格式的文檔大概如下圖所示,也可以直接參考其官方文檔。而文檔的第二個部分則是具體到每個函數、每個類的接口文檔。在開發階段,我們先按照格式要求寫好注釋文檔,然后通過開源工具Sphinx就可以自動化的生成API接口文檔。
安裝sphinx
這里我們直接使用python的包管理工具pip來安裝Sphinx以及一個read_the_docs
格式的python庫。如果不需要使用read_the_docs
格式也可以不安裝后者,只是后者在python的開源項目中還是最常用的一種文檔格式,並且可以配合read_the_docs網站進行API文檔的托管,因此推薦使用。
[dechin@dechin-manjaro circuit]$ python3 -m pip install sphinx
Requirement already satisfied: sphinx in /home/dechin/anaconda3/lib/python3.8/site-packages (3.4.3)
Requirement already satisfied: sphinxcontrib-htmlhelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.0.3)
Requirement already satisfied: docutils>=0.12 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (0.16)
Requirement already satisfied: sphinxcontrib-devhelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.0.2)
Requirement already satisfied: sphinxcontrib-serializinghtml in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.1.4)
Requirement already satisfied: sphinxcontrib-jsmath in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.0.1)
Requirement already satisfied: alabaster<0.8,>=0.7 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (0.7.12)
Requirement already satisfied: Pygments>=2.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (2.7.2)
Requirement already satisfied: requests>=2.5.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (2.24.0)
Requirement already satisfied: babel>=1.3 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (2.8.1)
Requirement already satisfied: sphinxcontrib-applehelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.0.2)
Requirement already satisfied: Jinja2>=2.3 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (2.11.2)
Requirement already satisfied: snowballstemmer>=1.1 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (2.0.0)
Requirement already satisfied: setuptools in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (50.3.1.post20201107)
Requirement already satisfied: sphinxcontrib-qthelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.0.3)
Requirement already satisfied: packaging in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (20.4)
Requirement already satisfied: imagesize in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx) (1.2.0)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx) (1.25.11)
Requirement already satisfied: certifi>=2017.4.17 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx) (2020.6.20)
Requirement already satisfied: chardet<4,>=3.0.2 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx) (3.0.4)
Requirement already satisfied: idna<3,>=2.5 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx) (2.10)
Requirement already satisfied: pytz>=2015.7 in /home/dechin/anaconda3/lib/python3.8/site-packages (from babel>=1.3->sphinx) (2020.1)
Requirement already satisfied: MarkupSafe>=0.23 in /home/dechin/anaconda3/lib/python3.8/site-packages (from Jinja2>=2.3->sphinx) (1.1.1)
Requirement already satisfied: six in /home/dechin/anaconda3/lib/python3.8/site-packages (from packaging->sphinx) (1.15.0)
Requirement already satisfied: pyparsing>=2.0.2 in /home/dechin/anaconda3/lib/python3.8/site-packages (from packaging->sphinx) (2.4.7)
[dechin@dechin-manjaro circuit]$ python3 -m pip install sphinx-rtd-theme
Collecting sphinx-rtd-theme
Downloading sphinx_rtd_theme-0.5.1-py2.py3-none-any.whl (2.8 MB)
|████████████████████████████████| 2.8 MB 74 kB/s
Requirement already satisfied: sphinx in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx-rtd-theme) (3.5.1)
Requirement already satisfied: sphinxcontrib-jsmath in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.0.1)
Requirement already satisfied: snowballstemmer>=1.1 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (2.0.0)
Requirement already satisfied: sphinxcontrib-serializinghtml in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.1.4)
Requirement already satisfied: imagesize in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.2.0)
Requirement already satisfied: alabaster<0.8,>=0.7 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (0.7.12)
Requirement already satisfied: requests>=2.5.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (2.24.0)
Requirement already satisfied: docutils>=0.12 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (0.16)
Requirement already satisfied: setuptools in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (50.3.1.post20201107)
Requirement already satisfied: Pygments>=2.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (2.7.2)
Requirement already satisfied: packaging in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (20.4)
Requirement already satisfied: sphinxcontrib-devhelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.0.2)
Requirement already satisfied: sphinxcontrib-applehelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.0.2)
Requirement already satisfied: sphinxcontrib-qthelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.0.3)
Requirement already satisfied: sphinxcontrib-htmlhelp in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (1.0.3)
Requirement already satisfied: babel>=1.3 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (2.8.1)
Requirement already satisfied: Jinja2>=2.3 in /home/dechin/anaconda3/lib/python3.8/site-packages (from sphinx->sphinx-rtd-theme) (2.11.2)
Requirement already satisfied: idna<3,>=2.5 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx->sphinx-rtd-theme) (2.10)
Requirement already satisfied: chardet<4,>=3.0.2 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx->sphinx-rtd-theme) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx->sphinx-rtd-theme) (2020.6.20)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/dechin/anaconda3/lib/python3.8/site-packages (from requests>=2.5.0->sphinx->sphinx-rtd-theme) (1.25.11)
Requirement already satisfied: pyparsing>=2.0.2 in /home/dechin/anaconda3/lib/python3.8/site-packages (from packaging->sphinx->sphinx-rtd-theme) (2.4.7)
Requirement already satisfied: six in /home/dechin/anaconda3/lib/python3.8/site-packages (from packaging->sphinx->sphinx-rtd-theme) (1.15.0)
Requirement already satisfied: pytz>=2015.7 in /home/dechin/anaconda3/lib/python3.8/site-packages (from babel>=1.3->sphinx->sphinx-rtd-theme) (2020.1)
Requirement already satisfied: MarkupSafe>=0.23 in /home/dechin/anaconda3/lib/python3.8/site-packages (from Jinja2>=2.3->sphinx->sphinx-rtd-theme) (1.1.1)
Installing collected packages: sphinx-rtd-theme
Successfully installed sphinx-rtd-theme-0.5.1
基於python的量子線路打印小項目
我們先看一下使用的方法以及效果,再回過頭來分析代碼實現的原理:
if __name__ == '__main__':
qc = QuantumCircuit(3)
qc.apply(0, 0)
qc.apply(1, (1,0))
qc.apply(1, (2,1))
qc.apply(1, (2,0))
qc.apply(2)
print (qc)
輸出結果如下所示(注意使用等寬字體):
|0> |0> |0>
| | |
| | h
| | |
| x ----- c
| | |
x ----- c |
| | |
x ----- | ----- c
| | |
m m m
這里我們就可以了解到,這個項目的核心功能就是通過構造一個量子線路的對象,並且對這個對象逐一的施加量子門操作,就可以輸出成對應的量子線路字符串。接下來我們再看看源碼實現:
# qcprinter.py
"""
The module used for print a quantum circuit in string format.
"""
class QuantumCircuit:
"""The class of quantum circuit from input quantum logical gates.
Parameters
----------
qubits : int
Totcal number of qubits used in this quantum circuit.
Returns
-------
str
The string format of quantum circuit.
How to use?
-------
>>> qc = QuantumCircuit(3)
>>> qc.apply(0, 0)
>>> qc.apply(1, (1,0))
>>> qc.apply(1, (2,1))
>>> qc.apply(1, (2,0))
>>> qc.apply(2)
>>> print (qc)
Example output
-------
>>> |0> |0> |0>
>>> | | |
>>> | | h
>>> | | |
>>> | x ----- c
>>> | | |
>>> x ----- c |
>>> | | |
>>> x ----- | ----- c
>>> | | |
>>> m m m
"""
def __init__(self, qubits=0):
self.qubits = qubits
self.str_circuit = ' |0>\t' * self.qubits + ' \n'
def __str__(self):
return self.str_circuit
def apply(self, gate_type, qubit_index=0):
"""The function used to apply quantum logical gates on quantum state.
Parameters
----------
gate_type : int
An index number represents for different type of quantum logical gates. 0 for h gate,
1 for cx gate and 2 for measure gate.
qubit_index: int, tuple, none
The qubit index quantum logical gates allpied on. If the gate_type is h, the qubit_index
would be int format. If the gate_type is cx, the qubit_index should be a tuple. If the
gate_type is m, that means do measurement to all qubits, thus you do not need to set
the value of qubit_index.
Returns
-------
str
The string format of quantum circuit.
"""
if gate_type == 0:
self.str_circuit += ' | \t' * self.qubits + '\n'
self.str_circuit += ' | \t' * (self.qubits - qubit_index - 1) + ' h \t' + ' | \t' * (qubit_index) + '\n'
elif gate_type == 1:
self.str_circuit += ' | \t' * self.qubits + '\n'
self.str_circuit += ' | \t' * (self.qubits - qubit_index[0] - 1) + ' x'
for i in range(qubit_index[0] - qubit_index[1] - 1):
self.str_circuit += ' ' + '-' * 5 + ' |'
self.str_circuit += ' ' + '-' * 5 + ' c \t'
self.str_circuit += ' | \t' * (qubit_index[1]) + '\n'
elif gate_type == 2:
self.str_circuit += ' | \t' * self.qubits + '\n'
self.str_circuit += ' m \t' * self.qubits + '\n'
else:
pass
在這個簡單的代碼實現中,我們主要是為量子線路的類設置了一個魔法函數__str__
,將我們所需要的量子線路的字符串作為整個對象的字符串返回值(關於python的魔法函數的使用方法可以參考前面這篇博客介紹)。這個字符串的類的核心功能是通過字符串拼接來實現的,我們不過多的贅述。這里為了方便操作,我們將量子邏輯門操作使用整型數字來替代:0
代表\(H\)門,1
代表\(CNOT\)門,2
代表全局的量子測量操作。同時,為了展示API文檔的制作過程,這里我們在類與函數內都寫了一部分的示例注釋代碼,在下一個章節介紹一下文檔的效果。
sphinx文檔生成與效果一覽
首先使用sphinx-quickstart
來生成一些配置文件:
[dechin@dechin-manjaro circuit]$ sphinx-quickstart
歡迎使用 Sphinx 3.5.1 快速配置工具。
Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).
Selected root path: .
You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> 獨立的源文件和構建目錄(y/n) [n]: y
The project name will occur in several places in the built documentation.
> 項目名稱: qcprinter
> 作者名稱: DechinPhy
> 項目發行版本 []: 1.0
If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.
For a list of supported codes, see
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.
> 項目語種 [en]: en
創建文件 /home/dechin/projects/2021-quantum/circuit/source/conf.py。
創建文件 /home/dechin/projects/2021-quantum/circuit/source/index.rst。
創建文件 /home/dechin/projects/2021-quantum/circuit/Makefile。
創建文件 /home/dechin/projects/2021-quantum/circuit/make.bat。
完成:已創建初始目錄結構。
You should now populate your master file /home/dechin/projects/2021-quantum/circuit/source/index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
在這一系列的配置之后,會在當前目錄下生成幾個新的文件(由於我們選擇了build和source分離的模式,因此這里會有2個目錄):
[dechin@dechin-manjaro circuit]$ ll
總用量 52
drwxr-xr-x 2 dechin dechin 4096 2月 23 00:04 build
-rw-r--r-- 1 dechin dechin 799 2月 23 00:04 make.bat
-rw-r--r-- 1 dechin dechin 638 2月 23 00:04 Makefile
-rw-r--r-- 1 dechin dechin 3055 2月 22 23:26 qcprinter.py
drwxr-xr-x 4 dechin dechin 4096 2月 23 00:04 source
在source目錄下會產生一些配置文件,這里我們需要修改其中的conf.py
文件:
[dechin@dechin-manjaro circuit]$ cd source/
[dechin@dechin-manjaro source]$ ll
總用量 16
-rw-r--r-- 1 dechin dechin 1884 2月 23 00:04 conf.py
-rw-r--r-- 1 dechin dechin 443 2月 23 00:04 index.rst
drwxr-xr-x 2 dechin dechin 4096 2月 23 00:04 _static
drwxr-xr-x 2 dechin dechin 4096 2月 23 00:04 _templates
可以參考樓主的配置方案,這里我們主要是將主題配置成了rtd
的格式,同時打開了autodoc
的選項以及通過sys
配置了索引目錄(索引目錄不配置的話,有可能導致找不到模塊,從而無法正常的生成API接口文檔):
[dechin@dechin-manjaro circuit]$ cat source/conf.py
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
project = 'qcprinter'
copyright = '2021, DechinPhy'
author = 'DechinPhy'
# The full version, including alpha/beta/rc tags
release = '1.0'
# -- General configuration ---------------------------------------------------
import sphinx_rtd_theme
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ["sphinx_rtd_theme", "sphinx.ext.autodoc", "sphinx.ext.autosummary"
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
執行sphinx-build
指令將source中的rst文檔編譯成html文檔,並輸出到build目錄下:
[dechin@dechin-manjaro circuit]$ sphinx-build source/ build/
正在運行 Sphinx v3.5.1
加載 pickled環境... 完成
構建 [mo]: 0 個 po 文件的目標文件已過期
構建 [html]: 0 個源文件的目標文件已過期
更新環境: 已添加 0,1 已更改,0 已移除
閱讀源... [100%] qcprinter
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit:4: WARNING: Unexpected section title or transition.
----------
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit:9: WARNING: Unexpected section title or transition.
-------
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit:14: WARNING: Unexpected section title or transition.
-------
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit:24: WARNING: Unexpected section title or transition.
-------
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit.apply:4: WARNING: Unexpected section title or transition.
----------
/home/dechin/projects/2021-quantum/circuit/qcprinter.py:docstring of qcprinter.QuantumCircuit.apply:15: WARNING: Unexpected section title or transition.
-------
查找當前已過期的文件... 沒有找到
pickling環境... 完成
檢查一致性... /home/dechin/projects/2021-quantum/circuit/source/modules.rst: WARNING: 文檔沒有加入到任何目錄樹中
完成
准備文件... 完成
寫入輸出... [ 33%] index 寫入輸出... [ 66%] modules 寫入輸出... [100%] qcprinter
generating indices... genindex py-modindex 完成
writing additional pages... search 完成
copying static files... 完成
copying extra files... 完成
dumping search index in English (code: en)... 完成
dumping object inventory... 完成
build 成功, 7 warnings.
HTML 頁面保存在 build 目錄。
在這個執行的過程中,有一部分的告警是跟注釋規范相關的,其實不用處理也沒有關系。接下來就可以打開build目錄,查看已經生成成功的html文檔,首先我們可以打開index.html,是常用的網頁主頁索引,大概內容如下圖所示:
我們先點擊這里的index和module看看內容,分別為下列的兩個圖所示:
最后在這個索引列表中我們點擊進入qcprinter
這個類中,去查看詳細的類的文檔說明:
相應的函數注釋內容也會在接口文檔中體現:
需要注意的是,如果相關的類或者函數是受保護的類型,那么在sphinx生成的文檔中是不會顯示的(構造過程中自動忽略)。
補充說明(2021.03.27)
如果在使用sphinx的過程中,發現代碼中的注釋文件並未被成功生成。如果成功執行的化,諸如module1.rst
和module2.rst
等會被自動的生成在source
目錄下。這些rst文件沒有被自動生成的情況下,可能需要使用sphinx-apidoc
去手動的添加:
[dechin@dechin-manjaro hiqfermion]$ sphinx-apidoc -f src/hiqfermion -o docs/source/
創建文件 docs/source/hiqfermion.rst。
創建文件 docs/source/hiqfermion.ansatzes.rst。
創建文件 docs/source/hiqfermion.drivers.rst。
創建文件 docs/source/hiqfermion.ops.rst。
創建文件 docs/source/hiqfermion.optimizers.rst。
創建文件 docs/source/hiqfermion.third_party.rst。
創建文件 docs/source/hiqfermion.transforms.rst。
創建文件 docs/source/hiqfermion.utils.rst。
創建文件 docs/source/modules.rst。
在上述示例中,src/hiqfermion
是源代碼的存放地址,而docs/source
是生成的rst文件存放的位置。一般我們需要先生成這些rst文件,再使用sphinx-build
執行文檔構建。
還有一點需要注意的是,如果我們直接使用sphinx-apidoc -f src/hiqfermion -o docs/source/
這樣的指令去生成的話,最終文檔中的結構都是hiqfermion.module1
和hiqfermion.module2
,這樣顯得不太簡潔,因為正常情況下我們需要的是module1
和module2
這樣比較直接的形式。此時我們可以更改其中的module.rst
文件。當然,首先我們需要逐一的去執行sphinx-apidoc來生成一些模塊化的rst文件:sphinx-apidoc -f src/hiqfermion/module1 -o docs/source/
以及sphinx-apidoc -f src/hiqfermion/module2 -o docs/source/
分開執行。這樣我們可以把module.rst
修改成這樣的形式:
module1
=======
.. toctree::
:maxdepth: 4
module1
module2
=======
.. toctree::
:maxdepth: 4
module2
這里rst文檔會自動搜尋同目錄下的module1.rst
和module2.rst
文件,並自動化的生成文檔。
總結概要
在這篇文章中,我們主要通過一個量子線路打印的python項目介紹,也順帶通過sphinx將python項目的注釋文檔自動化的生成API接口文檔,完成了一個項目開發及文檔輸出流程的簡要分析,在實戰中掌握更多的工具使用方法。
版權聲明
本文首發鏈接為:https://www.cnblogs.com/dechinphy/p/qcprinter.html
作者ID:DechinPhy
更多原著文章請參考:https://www.cnblogs.com/dechinphy/