Cipta plugin transpiler
Versi pakej
Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan menggunakan versi ini atau yang lebih baharu.
qiskit[all]~=2.3.0
Mencipta plugin transpiler adalah cara yang bagus untuk berkongsi kod transpilasi anda dengan komuniti Qiskit yang lebih luas, membolehkan pengguna lain memanfaatkan fungsi yang telah anda bangunkan. Terima kasih atas minat anda untuk menyumbang kepada komuniti Qiskit!
Sebelum mencipta plugin transpiler, anda perlu menentukan jenis plugin yang sesuai untuk situasi anda. Terdapat tiga jenis plugin transpiler:
- Plugin peringkat Transpiler. Pilih ini jika anda mentakrifkan pengurus laluan yang boleh menggantikan salah satu daripada 6 peringkat pengurus laluan berperingkat praset.
- Plugin sintesis unitar. Pilih ini jika kod transpilasi anda mengambil matriks unitar (diwakili sebagai tatasusunan Numpy) sebagai input dan menghasilkan penerangan Circuit kuantum yang melaksanakan unitar tersebut.
- Plugin sintesis peringkat tinggi. Pilih ini jika kod transpilasi anda mengambil "objek peringkat tinggi" seperti operator Clifford atau fungsi linear sebagai input dan menghasilkan penerangan Circuit kuantum yang melaksanakan objek peringkat tinggi tersebut. Objek peringkat tinggi diwakili oleh subkelas kelas Operation.
Setelah menentukan jenis plugin yang hendak dicipta, ikut langkah-langkah berikut untuk mencipta plugin:
- Cipta subkelas kelas plugin abstrak yang sesuai:
- PassManagerStagePlugin untuk plugin peringkat transpiler,
- UnitarySynthesisPlugin untuk plugin sintesis unitar, dan
- HighLevelSynthesisPlugin untuk plugin sintesis peringkat tinggi.
- Dedahkan kelas sebagai titik masuk setuptools dalam metadata pakej, biasanya dengan mengedit fail
pyproject.toml,setup.cfg, atausetup.pyuntuk pakej Python anda.
Tiada had bilangan plugin yang boleh ditakrifkan oleh satu pakej, tetapi setiap plugin mesti mempunyai nama yang unik. SDK Qiskit sendiri menyertakan beberapa plugin, yang namanya turut dikhaskan. Nama yang dikhaskan ialah:
- Plugin peringkat transpiler: Lihat jadual ini.
- Plugin sintesis unitar:
default,aqc,sk - Plugin sintesis peringkat tinggi:
| Kelas operasi | Nama operasi | Nama dikhaskan |
|---|---|---|
| Clifford | clifford | default, ag, bm, greedy, layers, lnn |
| LinearFunction | linear_function | default, kms, pmh |
| PermutationGate | permutation | default, kms, basic, acg, token_swapper |
Dalam bahagian seterusnya, kami menunjukkan contoh langkah-langkah ini untuk pelbagai jenis plugin. Dalam contoh-contoh ini, kami andaikan bahawa kami sedang mencipta pakej Python bernama my_qiskit_plugin. Untuk maklumat tentang mencipta pakej Python, anda boleh semak tutorial ini dari laman web Python.
Contoh: Cipta plugin peringkat transpiler​
Dalam contoh ini, kami mencipta plugin peringkat transpiler untuk peringkat layout (lihat Peringkat Transpiler untuk penerangan 6 peringkat saluran paip transpilasi terbina dalam Qiskit).
Plugin kami hanya menjalankan VF2Layout untuk beberapa percubaan yang bergantung pada tahap pengoptimuman yang diminta.
Pertama, kami mencipta subkelas PassManagerStagePlugin. Terdapat satu kaedah yang perlu dilaksanakan, iaitu pass_manager. Kaedah ini mengambil PassManagerConfig sebagai input dan mengembalikan pengurus laluan yang kami takrifkan. Objek PassManagerConfig menyimpan maklumat tentang Backend sasaran, seperti peta gandingannya dan Gate asas.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
# This import is needed for python versions prior to 3.10
from __future__ import annotations
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import VF2Layout
from qiskit.transpiler.passmanager_config import PassManagerConfig
from qiskit.transpiler.preset_passmanagers import common
from qiskit.transpiler.preset_passmanagers.plugin import (
PassManagerStagePlugin,
)
class MyLayoutPlugin(PassManagerStagePlugin):
def pass_manager(
self,
pass_manager_config: PassManagerConfig,
optimization_level: int | None = None,
) -> PassManager:
layout_pm = PassManager(
[
VF2Layout(
coupling_map=pass_manager_config.coupling_map,
properties=pass_manager_config.backend_properties,
max_trials=optimization_level * 10 + 1,
target=pass_manager_config.target,
)
]
)
layout_pm += common.generate_embed_passmanager(
pass_manager_config.coupling_map
)
return layout_pm
Sekarang, kami mendedahkan plugin dengan menambah titik masuk dalam metadata pakej Python kami.
Di sini, kami andaikan bahawa kelas yang kami takrifkan didedahkan dalam modul bernama my_qiskit_plugin, contohnya dengan diimport dalam fail __init__.py modul my_qiskit_plugin.
Kami mengedit fail pyproject.toml, setup.cfg, atau setup.py pakej kami (bergantung pada jenis fail yang anda pilih untuk menyimpan metadata projek Python anda):
- pyproject.toml
- setup.cfg
- setup.py
[project.entry-points."qiskit.transpiler.layout"]
"my_layout" = "my_qiskit_plugin:MyLayoutPlugin"
[options.entry_points]
qiskit.transpiler.layout =
my_layout = my_qiskit_plugin:MyLayoutPlugin
from setuptools import setup
setup(
# ...,
entry_points={
'qiskit.transpiler.layout': [
'my_layout = my_qiskit_plugin:MyLayoutPlugin',
]
}
)
Lihat jadual peringkat plugin transpiler untuk titik masuk dan jangkaan bagi setiap peringkat transpiler.
Untuk menyemak sama ada plugin anda berjaya dikesan oleh Qiskit, pasang pakej plugin anda dan ikut arahan di Plugin transpiler untuk menyenaraikan plugin yang dipasang, dan pastikan plugin anda muncul dalam senarai:
from qiskit.transpiler.preset_passmanagers.plugin import list_stage_plugins
list_stage_plugins("layout")
['default', 'dense', 'sabre', 'trivial']
Jika plugin contoh kami dipasang, nama my_layout akan muncul dalam senarai ini.
Jika anda ingin menggunakan peringkat transpiler terbina dalam sebagai titik permulaan untuk plugin peringkat transpiler anda, anda boleh mendapatkan pengurus laluan untuk peringkat transpiler terbina dalam menggunakan PassManagerStagePluginManager. Sel kod berikut menunjukkan cara untuk mendapatkan peringkat pengoptimuman terbina dalam untuk tahap pengoptimuman 3.
from qiskit.transpiler.preset_passmanagers.plugin import (
PassManagerStagePluginManager,
)
# Initialize the plugin manager
plugin_manager = PassManagerStagePluginManager()
# Here we create a pass manager config to use as an example.
# Instead, you should use the pass manager config that you already received as input
# to the pass_manager method of your PassManagerStagePlugin.
pass_manager_config = PassManagerConfig()
# Obtain the desired built-in transpiler stage
optimization = plugin_manager.get_passmanager_stage(
"optimization", "default", pass_manager_config, optimization_level=3
)
Contoh: Cipta plugin sintesis unitar​
Dalam contoh ini, kami akan mencipta plugin sintesis unitar yang hanya menggunakan laluan transpilasi terbina dalam UnitarySynthesis untuk mensintesis Gate. Sudah tentu, plugin anda sendiri akan melakukan sesuatu yang lebih menarik daripada itu.
Kelas UnitarySynthesisPlugin mentakrifkan antara muka dan kontrak untuk plugin sintesis unitar. Kaedah utamanya ialah
run,
yang mengambil tatasusunan Numpy yang menyimpan matriks unitar sebagai input
dan mengembalikan DAGCircuit yang mewakili Circuit yang disintesis daripada matriks unitar tersebut.
Selain kaedah run, terdapat beberapa kaedah sifat yang perlu ditakrifkan.
Lihat UnitarySynthesisPlugin untuk dokumentasi semua sifat yang diperlukan.
Mari cipta subkelas UnitarySynthesisPlugin kami:
import numpy as np
from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.converters import circuit_to_dag
from qiskit.dagcircuit.dagcircuit import DAGCircuit
from qiskit.quantum_info import Operator
from qiskit.transpiler.passes import UnitarySynthesis
from qiskit.transpiler.passes.synthesis.plugin import UnitarySynthesisPlugin
class MyUnitarySynthesisPlugin(UnitarySynthesisPlugin):
@property
def supports_basis_gates(self):
# Returns True if the plugin can target a list of basis gates
return True
@property
def supports_coupling_map(self):
# Returns True if the plugin can synthesize for a given coupling map
return False
@property
def supports_natural_direction(self):
# Returns True if the plugin supports a toggle for considering
# directionality of 2-qubit gates
return False
@property
def supports_pulse_optimize(self):
# Returns True if the plugin can optimize pulses during synthesis
return False
@property
def supports_gate_lengths(self):
# Returns True if the plugin can accept information about gate lengths
return False
@property
def supports_gate_errors(self):
# Returns True if the plugin can accept information about gate errors
return False
@property
def supports_gate_lengths_by_qubit(self):
# Returns True if the plugin can accept information about gate lengths
# (The format of the input differs from supports_gate_lengths)
return False
@property
def supports_gate_errors_by_qubit(self):
# Returns True if the plugin can accept information about gate errors
# (The format of the input differs from supports_gate_errors)
return False
@property
def min_qubits(self):
# Returns the minimum number of qubits the plugin supports
return None
@property
def max_qubits(self):
# Returns the maximum number of qubits the plugin supports
return None
@property
def supported_bases(self):
# Returns a dictionary of supported bases for synthesis
return None
def run(self, unitary: np.ndarray, **options) -> DAGCircuit:
basis_gates = options["basis_gates"]
synth_pass = UnitarySynthesis(basis_gates, min_qubits=3)
qubits = QuantumRegister(3)
circuit = QuantumCircuit(qubits)
circuit.append(Operator(unitary).to_instruction(), qubits)
dag_circuit = synth_pass.run(circuit_to_dag(circuit))
return dag_circuit
Jika anda mendapati input yang tersedia untuk kaedah run
tidak mencukupi untuk tujuan anda, sila buka isu menerangkan keperluan anda. Perubahan pada antara muka plugin, seperti menambah input pilihan tambahan, akan dilakukan dengan cara yang serasi ke belakang supaya tidak memerlukan perubahan daripada plugin sedia ada.
Semua kaedah yang diawali dengan supports_ dikhaskan pada kelas terbitan UnitarySynthesisPlugin sebagai sebahagian daripada antara muka. Anda tidak seharusnya mentakrifkan sebarang kaedah supports_* tersuai pada subkelas yang tidak ditakrifkan dalam kelas abstrak.
Sekarang, kami mendedahkan plugin dengan menambah titik masuk dalam metadata pakej Python kami.
Di sini, kami andaikan bahawa kelas yang kami takrifkan didedahkan dalam modul bernama my_qiskit_plugin, contohnya dengan diimport dalam fail __init__.py modul my_qiskit_plugin.
Kami mengedit fail pyproject.toml, setup.cfg, atau setup.py pakej kami:
- pyproject.toml
- setup.cfg
- setup.py
[project.entry-points."qiskit.unitary_synthesis"]
"my_unitary_synthesis" = "my_qiskit_plugin:MyUnitarySynthesisPlugin"
[options.entry_points]
qiskit.unitary_synthesis =
my_unitary_synthesis = my_qiskit_plugin:MyUnitarySynthesisPlugin
from setuptools import setup
setup(
# ...,
entry_points={
'qiskit.unitary_synthesis': [
'my_unitary_synthesis = my_qiskit_plugin:MyUnitarySynthesisPlugin',
]
}
)
Seperti sebelumnya, jika projek anda menggunakan setup.cfg atau setup.py dan bukannya pyproject.toml, lihat dokumentasi setuptools untuk cara menyesuaikan baris ini dengan situasi anda.
Untuk menyemak sama ada plugin anda berjaya dikesan oleh Qiskit, pasang pakej plugin anda dan ikut arahan di Plugin transpiler untuk menyenaraikan plugin yang dipasang, dan pastikan plugin anda muncul dalam senarai:
from qiskit.transpiler.passes.synthesis import unitary_synthesis_plugin_names
unitary_synthesis_plugin_names()
['aqc', 'clifford', 'default', 'gridsynth', 'sk']
Jika plugin contoh kami dipasang, nama my_unitary_synthesis akan muncul dalam senarai ini.
Untuk menampung plugin sintesis unitar yang mendedahkan pelbagai pilihan,
antara muka plugin mempunyai pilihan untuk pengguna menyediakan
kamus konfigurasi bebas bentuk. Ini akan dihantar ke kaedah run
melalui argumen kata kunci options. Jika plugin anda mempunyai pilihan konfigurasi ini, anda seharusnya mendokumentasikannya dengan jelas.
Contoh: Cipta plugin sintesis peringkat tinggi​
Dalam contoh ini, kami akan mencipta plugin sintesis peringkat tinggi yang hanya menggunakan fungsi terbina dalam synth_clifford_bm untuk mensintesis operator Clifford.
Kelas HighLevelSynthesisPlugin mentakrifkan antara muka dan kontrak untuk plugin sintesis peringkat tinggi. Kaedah utamanya ialah run.
Argumen kedudukan high_level_object ialah Operation yang mewakili objek "peringkat tinggi" yang hendak disintesis. Contohnya, ia boleh menjadi
LinearFunction atau
Clifford.
Argumen kata kunci berikut hadir:
targetmenentukan Backend sasaran, membolehkan plugin mengakses semua maklumat khusus sasaran, seperti peta gandingan, set Gate yang disokong, dan sebagainyacoupling_maphanya menentukan peta gandingan, dan hanya digunakan apabilatargettidak dinyatakan.qubitsmenentukan senarai Qubit yang menjadi asas objek peringkat tinggi ditakrifkan, sekiranya sintesis dilakukan pada Circuit fizikal. NilaiNonemenunjukkan bahawa susun atur belum dipilih dan Qubit fizikal dalam sasaran atau peta gandingan yang digunakan oleh operasi ini belum ditentukan.options, kamus konfigurasi bebas bentuk untuk pilihan khusus plugin. Jika plugin anda mempunyai pilihan konfigurasi ini anda seharusnya mendokumentasikannya dengan jelas.
Kaedah run mengembalikan QuantumCircuit
yang mewakili Circuit yang disintesis daripada objek peringkat tinggi tersebut.
Ia juga dibenarkan untuk mengembalikan None, menunjukkan bahawa plugin tidak dapat mensintesis objek peringkat tinggi yang diberikan.
Sintesis sebenar objek peringkat tinggi dilakukan oleh laluan transpiler
HighLevelSynthesis.
Selain kaedah run, terdapat beberapa kaedah sifat yang perlu ditakrifkan.
Lihat HighLevelSynthesisPlugin untuk dokumentasi semua sifat yang diperlukan.
Mari takrifkan subkelas HighLevelSynthesisPlugin kami:
from qiskit.synthesis import synth_clifford_bm
from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPlugin
class MyCliffordSynthesisPlugin(HighLevelSynthesisPlugin):
def run(
self,
high_level_object,
coupling_map=None,
target=None,
qubits=None,
**options,
) -> QuantumCircuit:
if high_level_object.num_qubits <= 3:
return synth_clifford_bm(high_level_object)
else:
return None
Plugin ini mensintesis objek bertaip Clifford yang mempunyai
paling banyak 3 Qubit, menggunakan kaedah synth_clifford_bm.
Sekarang, kami mendedahkan plugin dengan menambah titik masuk dalam metadata pakej Python kami.
Di sini, kami andaikan bahawa kelas yang kami takrifkan didedahkan dalam modul bernama my_qiskit_plugin, contohnya dengan diimport dalam fail __init__.py modul my_qiskit_plugin.
Kami mengedit fail pyproject.toml, setup.cfg, atau setup.py pakej kami:
- pyproject.toml
- setup.cfg
- setup.py
[project.entry-points."qiskit.synthesis"]
"clifford.my_clifford_synthesis" = "my_qiskit_plugin:MyCliffordSynthesisPlugin"
[options.entry_points]
qiskit.synthesis =
clifford.my_clifford_synthesis = my_qiskit_plugin:MyCliffordSynthesisPlugin
from setuptools import setup
setup(
# ...,
entry_points={
'qiskit.synthesis': [
'clifford.my_clifford_synthesis = my_qiskit_plugin:MyCliffordSynthesisPlugin',
]
}
)
name terdiri daripada dua bahagian yang dipisahkan oleh titik (.):
- Nama jenis Operation yang disintesis oleh plugin (dalam kes ini,
clifford). Perhatikan bahawa rentetan ini sepadan dengan atributnamekelas Operation, bukan nama kelas itu sendiri. - Nama plugin (dalam kes ini,
special).
Seperti sebelumnya, jika projek anda menggunakan setup.cfg atau setup.py dan bukannya pyproject.toml, lihat dokumentasi setuptools untuk cara menyesuaikan baris ini dengan situasi anda.
Untuk menyemak sama ada plugin anda berjaya dikesan oleh Qiskit, pasang pakej plugin anda dan ikut arahan di Plugin transpiler untuk menyenaraikan plugin yang dipasang, dan pastikan plugin anda muncul dalam senarai:
from qiskit.transpiler.passes.synthesis import (
high_level_synthesis_plugin_names,
)
high_level_synthesis_plugin_names("clifford")
['ag', 'bm', 'default', 'greedy', 'layers', 'lnn', 'rb_default']
Jika plugin contoh kami dipasang, nama my_clifford_synthesis akan muncul dalam senarai ini.
- Hantar plugin anda ke Ekosistem Qiskit!.
- Semak tutorial untuk contoh-contoh mentranspil dan menjalankan Circuit kuantum.