Lumaktaw sa pangunahing nilalaman
Ang proyektong ito ay nasa beta. Nakakita ng bug? Mag-bukas ng GitHub issue. May tanong o ideya? Magtanong sa Discussions — gusto naming marinig ang iyong feedback!
Gaano kaganda ang kalidad ng pagsasalin sa pahinang ito?

QESEM: Isang Qiskit Function ng Qedma

Tingnan ang API reference

Mga bersyon ng package

Ang code sa pahinang ito ay binuo gamit ang mga sumusunod na requirement. Inirerekomenda namin ang paggamit ng mga bersyong ito o mas bago.

qiskit[all]~=2.5.0
qiskit-ibm-runtime~=0.47.0
Tala

Ang Qiskit Functions ay isang experimental na feature na available lamang sa mga gumagamit ng IBM Quantum® Premium Plan, Flex Plan, at On-Prem (sa pamamagitan ng IBM Quantum Platform API) Plan. Nasa preview release status pa ito at maaaring magbago.

Pangkalahatang-ideya​

Kahit na malaki na ang pagbabago ng mga quantum processing unit sa mga nakaraang taon, ang mga error dahil sa ingay at mga kakulangan sa kasalukuyang hardware ay nananatiling pangunahing hamon para sa mga developer ng quantum algorithm. Habang papalapit ang larangan sa mga utility-scale na quantum computation na hindi na mapapatunayan nang klasikal, nagiging mas mahalaga ang mga solusyon para sa pagkansela ng ingay na may garantisadong katumpakan. Para malampasan ang hamong ito, binuo ng Qedma ang Quantum Error Mitigation (QESEM), na seamlessly na naka-integrate sa IBM Quantum Platform bilang isang Qiskit Function.

Gamit ang QESEM, maaaring patakbuhin ng mga gumagamit ang kanilang mga quantum circuit sa maingay na QPU para makakuha ng lubos na tumpak na mga resulta na walang error, na may napaka-episyenteng gastos sa QPU time, malapit sa mga pundamental na hangganan. Para magawa ito, ginagamit ng QESEM ang isang hanay ng mga proprietary na pamamaraan na binuo ng Qedma para sa pag-characterize at pagbabawas ng mga error. Kasama sa mga pamamaraan ng pagbabawas ng error ang gate optimization, noise-aware transpilation, error suppression (ES), at unbiased error mitigation (EM). Sa kombinasyong ito ng mga characterization-based na pamamaraan, nakakamit ng mga gumagamit ang maaasahan at error-free na mga resulta para sa mga generic na large-volume quantum circuit, na nagbubukas ng mga application na hindi maisasagawa nang iba.

Para sa buong paglalarawan ng mga pinagbabatayan na bahagi, pati na rin ang isang utility-scale na demonstrasyon, tingnan ang papel na Reliable high-accuracy error mitigation for utility-scale quantum circuits.

Paglalarawan​

Maaari mong gamitin ang QESEM function ng Qedma para madaling i-estimate at i-execute ang iyong mga circuit na may error suppression at mitigation, na nakakamit ng mas malalaking circuit volume at mas mataas na katumpakan. Para gamitin ang QESEM, magbibigay ka ng isang quantum circuit, isang hanay ng mga observable na susukat, isang target na statistical accuracy para sa bawat observable, at isang piniling QPU. Bago patakbuhin ang circuit sa target na katumpakan, maaari mong i-estimate ang kinakailangang QPU time batay sa isang analytical na kalkulasyon na hindi nangangailangan ng circuit execution. Kapag nasiyahan ka na sa QPU time estimation, maaari mo nang i-execute ang circuit gamit ang QESEM.

Kapag nag-execute ka ng circuit, nagpapatakbo ang QESEM ng device characterization protocol na akma sa iyong circuit, na nagbubunga ng maaasahang noise model para sa mga error na nangyayari sa circuit. Batay sa characterization, unang ipinapatupad ng QESEM ang noise-aware transpilation para i-map ang input circuit sa isang hanay ng mga physical qubit at gate, na nagpapababa ng ingay na nakakaapekto sa target na observable. Kasama dito ang mga natively available na gate (CX/CZ sa IBM® na mga device), pati na rin ang mga karagdagang gate na na-optimize ng QESEM, na bumubuo ng extended gate set ng QESEM. Pagkatapos, nagpapatakbo ang QESEM ng isang hanay ng mga characterization-based na ES at EM circuit sa QPU at kinokolekta ang kanilang mga resulta ng pagsukat. Pagkatapos ay klasikal na pinoproseso ang mga ito para magbigay ng unbiased na expectation value at error bar para sa bawat observable, na naaayon sa hiniling na katumpakan.

Pangkalahatang-ideya ng Qedma QESEM Napatunayang nagbibigay ang QESEM ng mga resulta na may mataas na katumpakan para sa iba't ibang quantum application at sa pinakamalaking circuit volume na makakamit ngayon. Nag-aalok ang QESEM ng mga sumusunod na feature para sa mga gumagamit, na ipinapakita sa seksyon ng mga benchmark sa ibaba:

  • Garantisadong katumpakan: Naglalabas ang QESEM ng mga unbiased na pagtatantya para sa mga expectation value ng mga observable. Ang EM method nito ay may mga theoretical na garantiya na - kasama ang cutting-edge na characterization ng Qedma - tinitiyak na ang mitigation ay nagko-converge sa noiseless na output ng circuit hanggang sa user-specified na katumpakan. Kumpara sa maraming heuristic na EM method na madaling magkaroon ng sistematikong error o bias, ang garantisadong katumpakan ng QESEM ay mahalaga para matiyak ang maaasahang mga resulta sa mga generic na quantum circuit at observable.
  • Scalability sa malalaking QPU: Ang QPU time ng QESEM ay depende sa circuit volume, ngunit independyente sa bilang ng mga qubit. Naipakita na ng Qedma ang QESEM sa pinakamalaking quantum device available ngayon, kabilang ang IBM Quantum 127-qubit Eagle at 133-qubit Heron na mga device.
  • Application-agnostic: Napatunayan na ang QESEM sa iba't ibang application, kabilang ang Hamiltonian simulation, VQE, QAOA, at amplitude estimation. Maaaring mag-input ang mga gumagamit ng anumang quantum circuit at observable na susukat, at makakuha ng tumpak na mga resulta na walang error. Ang mga limitasyon lamang ay idinidikta ng mga hardware specification at inilaan na QPU time, na nagtatakda ng naa-access na circuit volume at output accuracy. Kumpara rito, maraming solusyon sa pagbabawas ng error ang application-specific o gumagamit ng hindi kontroladong heuristic, na ginagawa silang hindi angkop para sa mga generic na quantum circuit at application.
  • Extended gate set: Sinusuportahan ng QESEM ang mga fractional-angle gate, at nagbibigay ng Qedma-optimized fractional-angle Rzz(θ)Rzz(\theta) gate sa mga IBM Quantum Heron at Eagle device. Ang extended gate set na ito ay nagpapahintulot ng mas episyenteng compilation at nagbubukas ng mga circuit volume na mas malaki ng hanggang 2x kumpara sa default na CX/CZ compilation.
  • Multibase observables: Sinusuportahan ng QESEM ang mga input observable na binubuo ng maraming non-commuting na Pauli string, tulad ng mga generic na Hamiltonian. Ang pagpili ng mga measurement basis at ang optimization ng QPU resource allocation (shots at circuits) ay awtomatikong ginagawa ng QESEM para maibaba ang kinakailangang QPU time para sa hiniling na katumpakan. Ang optimization na ito, na isinasaalang-alang ang hardware fidelity at execution rate, ay nagpapahintulot sa iyo na magpatakbo ng mas malalim na circuit at makamit ang mas mataas na katumpakan.

Mga Benchmark​

Nasubukan na ang QESEM sa malawak na iba't ibang kaso ng paggamit at application. Makakatulong ang mga sumusunod na halimbawa sa iyo sa pag-assess kung anong uri ng workload ang maaari mong patakbuhin gamit ang QESEM.

Isang mahalagang sukatan para ma-quantify ang kahirapan ng parehong error mitigation at classical simulation para sa isang partikular na circuit at observable ay ang active volume: ang bilang ng mga CNOT gate na nakakaapekto sa observable sa circuit. Ang active volume ay depende sa depth at width ng circuit, sa timbang ng observable, at sa estruktura ng circuit, na nagtatakda ng light cone ng observable. Para sa karagdagang detalye, tingnan ang talumpati mula sa 2024 IBM Quantum Summit. Nagbibigay ang QESEM ng partikular na malaking halaga sa high-volume regime, na nagbibigay ng maaasahang mga resulta para sa mga generic na circuit at observable.

Active volume

ApplicationBilang ng qubitDevicePaglalarawan ng circuitKatumpakanKabuuang orasPaggamit ng runtime
VQE circuit8Eagle (r3)21 total layers, 9 measurement bases, 1D chain98%35 min14 min
Kicked Ising28Eagle (r3)3 unique layers x 3 steps, 2D heavy-hex topology97%22 min4 min
Kicked Ising28Eagle (r3)3 unique layers x 8 steps, 2D heavy-hex topology97%116 min23 min
Trotterized Hamiltonian simulation40Eagle (r3)2 unique layers x 10 Trotter steps, 1D chain97%3 hours25 min
Trotterized Hamiltonian simulation119Eagle (r3)3 unique layers x 9 Trotter steps, 2D heavy-hex topology95%6.5 hours45 min
Kicked Ising136Heron (r2)3 unique layers x 15 steps, 2D heavy-hex topology99%52 min9 min

Ang katumpakan dito ay sinusukat kumpara sa ideal na halaga ng observable: ⟨O⟩ideal−ϵ⟨O⟩ideal\frac{\langle O \rangle_{ideal} - \epsilon}{\langle O \rangle_{ideal}}, kung saan ang 'ϵ\epsilon' ay ang absolute precision ng mitigation (itinakda ng input ng gumagamit), at ang ⟨O⟩ideal\langle O \rangle_{ideal} ay ang observable sa noiseless na circuit. Ang 'Runtime usage' ay sumusukat ng paggamit ng benchmark sa batch mode (kabuuan ng paggamit ng mga indibidwal na job), habang ang 'total time' ay sumusukat ng paggamit sa session mode (experiment wall time), na kinabibilangan ng karagdagang classical at communication time. Available ang QESEM para sa execution sa parehong mode, para magamit ng mga gumagamit ang kanilang mga available na mapagkukunan nang pinakamabuti.

Ang mga 28-qubit Kicked Ising circuit ay nagsi-simulate ng Discrete Time Quasicrystal na pinag-aralan ni Shinjo et al. (tingnan ang arXiv 2403.16718 at Q2B24 Tokyo) sa tatlong magkakaugnay na loop ng ibm_kawasaki. Ang mga parameter ng circuit na ginamit dito ay (θx,θz)=(0.9π,0)(\theta_x, \theta_z) = (0.9 \pi, 0), na may ferromagnetic na paunang estado ∣ψ0⟩=∣0⟩⊗n| \psi_0 \rangle = | 0 \rangle ^{\otimes n}. Ang sinusukat na observable ay ang absolute na halaga ng magnetization M=∣128∑i=027⟨Zi⟩∣M = |\frac{1}{28} \sum_{i=0}^{27} \langle Z_i \rangle|. Ang utility-scale na Kicked Ising experiment ay pinatakbo sa 136 pinakamahusay na qubit ng ibm_fez; ang partikular na benchmark na ito ay pinatakbo sa Clifford angle na (θx,θz)=(π,0)(\theta_x, \theta_z) = (\pi, 0), kung saan ang active volume ay mabagal na lumalaki kasabay ng circuit depth, na — kasama ang mataas na fidelity ng device — nagbibigay-daan sa mataas na katumpakan sa maikling runtime.

Ang mga Trotterized Hamiltonian simulation circuit ay para sa isang Transverse-Field Ising model sa mga fractional angle: (θzz,θx)=(π/4,π/8)(\theta_{zz}, \theta_x) = (\pi / 4, \pi /8) at (θzz,θx)=(π/6,π/8)(\theta_{zz}, \theta_x) = (\pi / 6, \pi / 8) ayon sa pagkakasunod (tingnan ang Q2B24 Tokyo). Ang utility-scale na circuit ay pinatakbo sa 119 pinakamahusay na qubit ng ibm_brisbane, habang ang 40-qubit na eksperimento ay pinatakbo sa pinakamahusay na available na chain. Ang katumpakan ay iniulat para sa magnetization; nakamit din ang mga resulta na may mataas na katumpakan para sa mga observable na may mas mataas na timbang.

Ang VQE circuit ay binuo kasama ang mga mananaliksik mula sa Center for Quantum Technology and Applications sa Deutsches Elektronen-Synchrotron (DESY). Ang target na observable dito ay isang Hamiltonian na binubuo ng malaking bilang ng mga non-commuting na Pauli string, na binibigyang-diin ang optimized na performance ng QESEM para sa multi-basis observable. Ang mitigation ay inilapat sa isang classically-optimized na ansatz; kahit hindi pa nailalathala ang mga resultang ito, makukuha ang parehong kalidad ng mga resulta para sa iba't ibang circuit na may magkakahawig na katangiang pang-istruktura.

Pagsisimula​

Mag-authenticate gamit ang iyong IBM Quantum Platform API key, at piliin ang QESEM Qiskit Function tulad ng sumusunod. (Ipinapalagay ng snippet na ito na na-save mo na ang iyong account sa iyong lokal na environment.)

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"qiskit": "qiskit", "qiskit_ibm_catalog": "qiskit-ibm-catalog", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import qiskit
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# verify that you have access to the function
catalog.list()
# load the function
qesem_function = catalog.load("qedma/qesem")

Mga Halimbawa​

Halimbawa ng time estimation job​

Ang time estimation job ay kapaki-pakinabang para sa pagtatantya ng QPU time na kinakailangan para sa isang partikular na pub at backend_name. Ang backend_name ay maaari ring itakda sa anumang simulator backend; halimbawa, fake_fez.

Gumagamit ang QESEM ng quasi-probabilistic, characterization-based EM method. Ang method na ito ay may QPU time overhead na humigit-kumulang lumalaki (nag-i-scale) ayon sa:

TQPU=aeαIF⋅Vaϵ2+bT_{QPU} = a \frac{e^{\alpha IF\cdot V_a}}{\epsilon^2} + b

Kung saan ang VaV_a ay ang active volume ng circuit, ang ϵ\epsilon ay ang target precision, at ang IFIF ay ang infidelity ng mga native gate.

Tandaan na ang "estimate_time_only": "empirical" ay gumagamit ng ilang minuto ng QPU time para tantiyahin ang oras na kinakailangan para sa job (kung ang backend ay isang tunay na device; kung ito ay isang simulator, walang QPU time na ginagamit). Karaniwang tatagal ito ng humigit-kumulang 5 minuto, ngunit hindi hihigit sa 10 minuto. Kung malaki ang pagbabago ng infidelity sa pagitan ng empirical time estimation job at ng mitigation job, malaki rin ang magiging pagbabago ng QPU time.

Para magsimula, subukan ang pangunahing halimbawang ito ng pag-estimate ng kinakailangang QPU time para patakbuhin ang QESEM para sa isang partikular na pub:

# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend_name = service.least_busy().name
backend_name = "fake_fez"

circ = qiskit.QuantumCircuit(5)
circ.cx(0, 1)
circ.cx(2, 3)
circ.cx(1, 2)
circ.cx(3, 4)

avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)
other_observable = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("ZZ", [0, 1], 1.0), ("XZ", [1, 4], 0.5)], num_qubits=5
)

time_estimation_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
options={
"estimate_time_only": "empirical",
},
backend_name=backend_name, # example: "fake_fez", "ibm_fez"
)
time_estimate_result = (
time_estimation_job.result()
) # a list of results per pub (circuit)

Inilalarawan ng sumusunod na code snippet kung paano kunin ang iba't ibang execution metrics mula sa time estimation job (estimate_time_only ay itinakda):

pub_result = time_estimate_result[0]

print(
f"The estimated QPU time for mitigation for this PUB is: {pub_result.metadata['time_estimation_sec']}"
)
print(
f"The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f"Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f"Total shots: {pub_result.metadata['total_shots']}")
print(f"Resource usage breakdown: {pub_result.metadata['resource_usage']}")
The estimated QPU time for mitigation for this PUB is: 300
The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): 0
Gates fidelity measured during the experiment: {'CZ': 0.9951354916722668, 'ID1Q': 0.9991246627329172}
Total shots: 220000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 33.6066133165732, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 184.53575124032795, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

Kapag pinagana ang empirical time estimation, nagpapatakbo ang QESEM ng kaunting bilang ng mga circuit para magbigay ng mas tumpak na QPU time estimate. Ang mga resulta ng mitigation mula sa mga circuit na ito ay makikita sa empirical_estimation_mitigation_results field ng job.

Dahil ang mga resultang ito ay hango sa limitadong sample ng mga circuit, higit na mas mababa ang katumpakan ng mga ito kumpara sa mga panghuling resulta na nakukuha mula sa kumpletong QESEM mitigation job. Gayunpaman, kapag maliit ang circuit o mababa ang target precision, ang mitigation na isinagawa sa panahon ng empirical time estimation ay maaaring sapat na para maabot ang nais na precision, at maaaring hindi na kailangan ang buong mitigation job.

Ang empirical_estimation_mitigation_results field ay isang list ng mga PrimitiveResult object kada input parameter. Kung hindi parametrized ang circuit, ang list ay magiging haba na 1.

empirical_estimation_mitigation_results = time_estimate_result[0].metadata[
"empirical_estimation_mitigation_results"
][0] # a list per parameter
print("Partial results for the observables:")

print(
f" Mitigated expectation values: {empirical_estimation_mitigation_results.data.evs}"
)
print(
f" Mitigated error bars: {empirical_estimation_mitigation_results.data.stds}"
)
print(
f" Number of shots used for mitigation: {empirical_estimation_mitigation_results.metadata['mitigation_shots']}"
)
transpiled_circ = empirical_estimation_mitigation_results.metadata[
"transpiled_circ"
]
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Number of measurement bases: {transpiled_circ['num_measurement_bases']}\n"
)

# results per obs
emp_obs_results = empirical_estimation_mitigation_results.metadata["results"][
0
]
# print(f"Results for each observable: {results}")
print("Results for each observable:")

for i, (obs_array, result_dict) in enumerate(emp_obs_results):
# obs_array, result_dict = results
print(f"Observable {i+1}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} \u00b1 {result_dict['qesem']['error_bar']}"
)
Partial results for the observables:
Mitigated expectation values: [1.00347302 1.00693905]
Mitigated error bars: [0.00304061 0.00714276]
Number of shots used for mitigation: 180000
Qubit mapping: [[[0, 136], [1, 143], [2, 142], [3, 141], [4, 140]]]
Number of measurement bases: 2

Results for each observable:
Observable 1: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.003473015776871 ± 0.0030406128032204015
Observable 2: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0069390542613554 ± 0.0071427606736885925

Halimbawa ng QESEM mitigation job​

Ang sumusunod na halimbawa ay nagpapatakbo ng isang QESEM job:

sample_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
backend_name=backend_name, # example: "ibm_fez"
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)

Para sa detalyadong paglalarawan ng bawat input field at opsyon, tingnan ang QESEM API reference. Maaari mong gamitin ang mga pamilyar na Qiskit Serverless API para suriin ang status ng iyong Qiskit Function workload o makuha ang mga resulta:

# Print the ID so you can use it later, if necessary
print(sample_job.job_id)
print(sample_job.status())
sample_result = sample_job.result()
3ac6b2df-15b0-4dc0-8f48-cf14bd20a1c8
DONE

Ang sumusunod na code snippet ay nagpapakita kung paano kunin ang mga resulta ng mitigation at execution metrics. Naglalaman ang mga ito ng mahahalagang data na nagpapahintulot sa mas malalim na pag-unawa kung paano nakakaapekto ang iba't ibang parameter sa QESEM execution. Maaari rin itong maging kaugnay kapag nagsusulat ng papel batay sa iyong pananaliksik.

for pub_idx, pub_result in enumerate(
sample_result
): # each element in the list is a result for a different pub, here we sent only one pub
print(f"\nPUB {pub_idx}:")
print(
f" The QPU time that this job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f" Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f" Total shots: {pub_result.metadata['total_shots']}")
print(
f" Number of shots used for mitigation: {pub_result.metadata['mitigation_shots']}"
)
print(
f" Resource usage breakdown: {pub_result.metadata['resource_usage']}"
)
PUB 0:
The QPU time that this job took is (here it is 0 because we used fake_fez): 0.0
Gates fidelity measured during the experiment: {'CZ': 0.9953704216147041, 'ID1Q': 0.9991834123567518}
Total shots: 446000
Number of shots used for mitigation: 194000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 32.52745003718883, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 257.850521848537, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

Sa metadata["results"], ang mga resulta ay pinangkat muna ayon sa circuit instance at pagkatapos ayon sa observable.

print("Full QESEM mitigation results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")

print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata.get("noisy_results")
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")

print(" Transpiled circuits:")
for circ_idx, transpiled_circ in enumerate(
pub_result.metadata["transpiled_circs"]
):
print(f" Circuit {circ_idx}:")
# print(f" Circuit: \n {transpiled_circ['circuit']}") # not printing it because it's long but you can see the transpiled circuit itself
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Measurement bases: {transpiled_circ['num_measurement_bases']}"
)

print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Full QESEM mitigation results:

PUB 0:
Mitigated expectation values: [1.00648343 1.00636289]
Mitigated error bars: [0.00253812 0.00693586]
Unmitigated expectation values: [0.98031429 0.96357143]
Unmitigated error bars: [0.00124128 0.00578812]
Transpiled circuits:
Circuit 0:
Qubit mapping: [[[0, 140], [1, 141], [2, 142], [3, 143], [4, 136]]]
Measurement bases: 2
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.0064834305181962 ± 0.002538119914534849
Unmitigated value: 0.9803142857142859 ± 0.0012412835813609938
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0063628870614818 ± 0.006935859820870656
Unmitigated value: 0.9635714285714285 ± 0.005788121870526659

Breakdown ng mga pangunahing resulta:

  • mitigated: ang ganap na mitigated na QESEM expectation value.
  • unmitigated: ang raw physical-noise result na walang error mitigation.

Mga resulta ng QESEM heuristic extrapolation​

Sa isang standard na pagpapatakbo ng QESEM na may iisang precision float, kasama rin sa mga resulta ang mga awtomatikong available na noise-scaling point na ginagamit para sa QESEM heuristic. Ang mga puntong ito ay kinakalkula nang walang karagdagang QPU resources.

Ang scale na 1.0 ay kumakatawan sa physical device noise level na may readout mitigation (REM), habang ang scale na 2.0 ay ang komplementaryong noise-amplified na punto, mayroon ding REM. Ang mga puntong ito ay ginagamit para makabuo ng qesem_heuristic na resulta.

  • qesem_heuristic: isang ZNE-style na pagtatantya na kinakalkula mula sa available na noise-scaled data. Sa kasalukuyan, gumagamit ito ng exponential extrapolation.

  • noise_scaling.results_with_REM: mga expectation value sa iba't ibang noise scale, lahat may readout mitigation (REM).

Isang banayad ngunit mahalagang detalye ay ang resulta ng scale na 1.0 ay hindi kapareho ng resultang unmitigated. Parehong tumutugma sa physical device noise level, ngunit ang puntong scale 1.0 ay may kasamang readout mitigation, habang ang unmitigated ay wala.

print("QESEM heuristic results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
qesem_heuristic = result_dict["qesem_heuristic"][0]
print(" QESEM heuristic:")
print(
f" Value: {qesem_heuristic['value']} ± {qesem_heuristic['error_bar']}"
)
print(
f" Extrapolation: {qesem_heuristic['extrapolation']}"
)
print(
f" Scale factors: {qesem_heuristic['scale_factors']}"
)
noise_scaling = result_dict["noise_scaling"]
print(" Noise scaling results:")
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QESEM heuristic results:

PUB 0:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM heuristic:
Value: 1.0008161638888535 ± 0.0038859458884403964
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9918395459270772 ± 0.0012565417579355634
Scale factor 2.0: 0.982943441922748 ± 0.0028919278067695018
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM heuristic:
Value: 0.9960853148925298 ± 0.013811635038961175
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9902860583785115 ± 0.005921236914723409
Scale factor 2.0: 0.984520565414274 ± 0.006909522262347639
tala

Ang mga sumusunod na halimbawa ay nakatuon sa feature-specific na mga input at resulta, kaya hindi nila ini-print ang buong execution metrics sa bawat pagkakataon. Ang top-level metadata na ipinakita kanina, tulad ng total_qpu_time, gate_fidelities, total_shots, mitigation_shots, at resource_usage, ay available din para sa mga job na ito.

Ang ilang variable mula sa mga naunang halimbawa, kabilang ang backend, mga observable, at mga base circuit parameter, ay ginagamit muli sa ibaba para sa kaiklian.

tala

Lahat ng sumusunod na halimbawa ay maaari ring patakbuhin gamit ang empirical time estimation. Para i-enable ito, ipasa ang "estimate_time_only": "empirical" sa function options.

Halimbawa ng parameterized circuit​

Maraming algorithm ang nagsusuri ng parehong circuit sa ilang parameter value. Ang pagpapadala ng parameterized circuit bilang isang QESEM job ay nagpapahintulot sa QESEM na pagsaluhan ang characterization at calibration sa buong circuit instances, na maaaring magpababa ng QPU-time overhead kumpara sa pagpapatakbo ng magkakahiwalay na job.

Ang pagsusumite ng parameterized circuit ay nangangailangan ng paggamit ng "minimal_with_layout_opt" na transpilation level. Ang mga circuit na isinumite sa antas na ito ay dapat na nakaexpress na gamit ang basis gates ng backend, depende sa backend. Sa antas na ito, pinapanatili ng QESEM ang isinumiteng structure na kasing lapit hangga't maaari sa input circuit, iginagalang ang mga barrier sa panahon ng layerification (pagpapangkat ng mga operation sa mga layer ng parallel two-qubit gates), at hinahawakan pa rin ang hardware mapping papunta sa high-fidelity qubits at device connectivity nang awtomatiko.

Sa praktika, nangangahulugan ito na dapat mong i-transpile ang mga circuit papunta sa basis gates ng target backend bago isumite. Ipinapakita sa ibaba ang isang simpleng halimbawa ng basis-gate transpilation.

Kasalukuyang sinusuportahan ng QESEM ang isang observable lamang kada parameter set. Ang dalawang parameter row sa ibaba ay naka-zip sa dalawang observable: ang unang row ay sinusukat gamit ang avg_magnetization, at ang ikalawang row ay sinusukat gamit ang other_observable.

# Transpile to the backend basis gates only. With minimal_with_layout_opt, QESEM handles hardware mapping/connectivity and observable layout internally.
from qiskit_ibm_runtime.fake_provider import FakeFez

backend = FakeFez()
basis = backend.operation_names
print(basis)

param0 = qiskit.circuit.Parameter("param0")
param1 = qiskit.circuit.Parameter("param1")
parametrized_circ = qiskit.QuantumCircuit(5)
parametrized_circ.rx(param0, 0)
parametrized_circ.rx(param1, 1)
parametrized_circ.cx(0, 1)
parametrized_circ.cx(2, 3)
parametrized_circ.cx(1, 2)
parametrized_circ.cx(3, 4)

parametrized_circ = qiskit.transpile(
parametrized_circ, basis_gates=basis, optimization_level=1
)
parametrized_parameter_values = [[0.5, 0.1], [0.0, 0.6]]
parametrized_observables = [avg_magnetization, other_observable]

parametrized_job = qesem_function.run(
pubs=[
(
parametrized_circ,
parametrized_observables,
parametrized_parameter_values,
0.1,
)
],
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
},
)
print(parametrized_job.job_id)
print(parametrized_job.status())
d1b0e29b-196c-4896-aec6-44a268ebd874
DONE
parametrized_result = parametrized_job.result()
print("Parameterized circuit QESEM results:")

for pub_idx, pub_result in enumerate(parametrized_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each parameter value:")
for param_idx, param_results in enumerate(pub_result.metadata["results"]):
print(
f" Parameter set {param_idx}: {parametrized_parameter_values[param_idx]}"
)
for obs_idx, (obs_array, result_dict) in enumerate(param_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Parameterized circuit QESEM results:

PUB 0:
Mitigated expectation values: [0.92392021 0.82517653]
Mitigated error bars: [0.00565281 0.00616016]
Unmitigated expectation values: [0.9028 0.78771429]
Unmitigated error bars: [0.00335142 0.00925413]
Results for each parameter value:
Parameter set 0: [0.5, 0.1]
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.923920210615709 ± 0.005652811570890183
Unmitigated value: 0.9028 ± 0.0033514176105045447
Parameter set 1: [0.0, 0.6]
Observable 0: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 0.8251765289285893 ± 0.006160161743353999
Unmitigated value: 0.7877142857142858 ± 0.009254130564027902

Halimbawa ng multi-pub​

Kapaki-pakinabang ang multi-pub execution kapag gusto mong patakbuhin ang ilang magkakaugnay na circuit sa isang QESEM job. Tulad ng parameterized execution, maaari nitong mabawasan ang overhead dahil kaya ng QESEM na pagsaluhan ang characterization at calibration sa buong circuit instances imbes na ulitin ito sa magkakahiwalay na job.

Lalo itong kapaki-pakinabang para sa mga circuit na may shared layer structure, tulad ng mga Trotter-type na workload, kung saan ang iba't ibang circuit ay gumagamit muli ng parehong mga natatanging layer. Sa kasong iyon, ang pagpapatakbo sa mga ito nang sabay-sabay ay maaaring magpababa ng characterization cost kumpara sa mga independiyenteng QESEM job.

Ang mga multi-pub job ay nangangailangan ng "transpilation_level": "minimal_with_layout_opt". Tulad ng sa parameterized na halimbawa, ang mga circuit ay dapat i-transpile papunta sa basis gates ng target backend bago isumite. Hinahawakan ng QESEM ang device connectivity, layout, at mapping papunta sa high-fidelity qubits nang internal.

Ang bawat PUB sa ibaba ay naglalaman ng isang circuit at ng parehong dalawang observable na ginamit kanina sa notebook, kaya ang naibalik na PrimitiveResult ay naglalaman ng isang PubResult kada input circuit.

Ang halimbawa sa ibaba ay gumagamit ng dalawang simpleng Trotter circuit na may parehong layer pattern: mayroong isang Trotter layer ang circ_a, at inuulit ng circ_b ang parehong layer pattern nang dalawang beses. Ginagawa nitong explicit ang shared structure.

def make_trotter_circuit(num_qubits, num_layers, zz_angle=0.2, x_angle=0.1):
trotter_circ = qiskit.QuantumCircuit(num_qubits)
for _ in range(num_layers):
for q in range(num_qubits):
trotter_circ.rx(x_angle, q)
trotter_circ.barrier()
for q in range(0, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
for q in range(1, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
return trotter_circ

circ_a = make_trotter_circuit(num_qubits=5, num_layers=1)
circ_b = make_trotter_circuit(num_qubits=5, num_layers=2)
multi_pubs = [
(
qiskit.transpile(qci, basis_gates=basis, optimization_level=1),
[avg_magnetization, other_observable],
)
for qci in [circ_a, circ_b]
]

multi_circ_job = qesem_function.run(
pubs=multi_pubs,
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
"default_precision": 0.1,
},
)
print(multi_circ_job.job_id)
print(multi_circ_job.status())
e34565b8-7262-4133-a120-de42ce624a99
DONE
multi_circ_result = multi_circ_job.result()
print("Multi-pub QESEM results:")

for pub_idx, pub_result in enumerate(multi_circ_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Multi-pub QESEM results:

PUB 0:
Mitigated expectation values: [0.99502406 1.02209332]
Mitigated error bars: [0.00483819 0.00707488]
Unmitigated expectation values: [0.96934286 0.97271429]
Unmitigated error bars: [0.00124855 0.00617294]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.9950240647925642 ± 0.004838188086259301
Unmitigated value: 0.9693428571428573 ± 0.0012485470362492692
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0220933230604674 ± 0.007074884384355636
Unmitigated value: 0.9727142857142859 ± 0.006172939375512439

PUB 1:
Mitigated expectation values: [0.98850017 1.02555188]
Mitigated error bars: [0.0077912 0.01672652]
Unmitigated expectation values: [0.93682857 0.95371429]
Unmitigated error bars: [0.00156245 0.00665735]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.988500171577252 ± 0.007791203181151346
Unmitigated value: 0.9368285714285716 ± 0.001562451883089579
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.02555188098689 ± 0.016726524388086233
Unmitigated value: 0.9537142857142858 ± 0.006657345655544263

Halimbawa ng Quasi-probabilistic Error Tuning (QET)​

Humihiling ang Quasi-probabilistic Error Tuning (QET) ng mga expectation value sa mga piniling noise scale factor. Kapaki-pakinabang ito para sa custom na noise-scaling studies at mga Zero-Noise Extrapolation workflow. Ang scale na 1.0 ay ang physical noise level, ang mga value sa pagitan ng 0.0 at 1.0 ay bahagyang binabawasan ang noise, at ang mga value na higit sa 1.0 ay pinapalakas ang noise.

Para gamitin ang QET kasama ng Qiskit Function, magpasa ng dictionary bilang PUB precision. Ini-map ng dictionary ang bawat hiniling na noise scale sa target nitong precision. Ang mga naibalik na resulta ng scale-factor ay nakaimbak sa noise_scaling.results_with_REM at may kasamang readout mitigation. Kaya hindi kapareho ng unmitigated value ang puntong 1.0 na scale, dahil may kasamang readout mitigation ang 1.0 samantalang wala ito sa unmitigated.

Kapag humiling ng scale, ibinabalik din ng QESEM ang complementary scale sa paligid ng 1.0 nang walang karagdagang paggamit ng QPU. Halimbawa, ang paghiling ng 0.5 ay maaari ring magbalik ng 1.5, at ang paghiling ng 1.3 ay maaari ring magbalik ng 0.7. Hindi ginagarantiya ang precision sa complementary scale.

noise_scale_precision = {0.5: 0.15, 1.3: 0.2}

qet_job = qesem_function.run(
pubs=[
(
circ,
[avg_magnetization, other_observable],
None,
noise_scale_precision,
)
],
backend_name=backend_name,
options={"max_execution_time": 300},
)
print(qet_job.job_id)
print(qet_job.status())
8195fa58-f037-4651-8715-36ce1cdc5521
DONE
qet_result = qet_job.result()
print("QET noise-scaling results:")

for pub_idx, pub_result in enumerate(qet_result):
print(f"\nPUB {pub_idx}:")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
noise_scaling = result_dict["noise_scaling"]
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QET noise-scaling results:

PUB 0:
Unmitigated expectation values: [0.97822857 0.96171429]
Unmitigated error bars: [0.00123812 0.00672958]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 0.9938730340199383 ± 0.0032116907357568275
Scale factor 0.7: 0.9963976191853445 ± 0.00036300258869586616
Scale factor 1.0: 0.9898115079506586 ± 0.0012525947426560995
Scale factor 1.3: 0.9864667065580341 ± 0.002633221613518526
Scale factor 1.5: 0.9838755527197551 ± 0.002948417797996015
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 1.0006538544450332 ± 0.002121742014777343
Scale factor 0.7: 1.0004159801523036 ± 0.0021671375357823794
Scale factor 1.0: 0.9898058846339917 ± 0.00690183710903159
Scale factor 1.3: 0.9948946719997267 ± 0.002146532859610311
Scale factor 1.5: 0.9927220368192772 ± 0.0020875057190323882

Kunin ang mga mensahe ng error​

Kung ang status ng iyong workload ay ERROR, gamitin ang job.result() para kunin ang mensahe ng error tulad ng sumusunod:

# Get the result and truncate for readability
result = sample_job.result()
result_str = str(result)
max_length = 500 # Adjust this value as necessary

if len(result_str) > max_length:
truncated = (
result_str[:max_length]
+ f"... (truncated {len(result_str) - max_length} characters)"
)
else:
truncated = result_str

print(truncated)
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(2,), dtype=float64>), stds=np.ndarray(<shape=(2,), dtype=float64>), shape=(2,)), metadata={'gate_fidelities': {'CZ': 0.9979444718552628, 'ID1Q': 0.9991994239814883}, 'total_shots': 498600, 'mitigation_shots': 223400, 'transpiled_circs': [{'circuit': 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[76] c0;\nqubit[76] q0;\nrx(0) q0[54];\nrx(0) q0[59];\nrx(0) q0[75];\nrz(pi/2) q0[54];\nrz(pi/2) q0[59];\nrz(pi/2) q0[75];\nrx(pi/2) q0[54];\nr... (truncated 3771 characters)

Makakuha ng suporta​

Nandito ang support team ng Qedma para tumulong! Kung nakatagpo ka ng anumang isyu o mayroon kang mga tanong tungkol sa paggamit ng QESEM Qiskit Function, huwag mag-atubiling makipag-ugnayan. Ang aming mga kaalamang at magiliw na support staff ay handang tumulong sa iyo sa anumang teknikal na alalahanin o katanungan na maaaring mayroon ka.

Maaari kang mag-email sa amin sa support@qedma.com para sa tulong. Pakisama ang pinakamaraming detalye hangga't maaari tungkol sa isyung nararanasan mo para matulungan kaming magbigay ng mabilis at tumpak na tugon. Maaari ka ring makipag-ugnayan sa iyong dedikadong Qedma POC representative sa pamamagitan ng email o telepono.

Para matulungan kaming tulungan ka nang mas episyente, pakibigay ang sumusunod na impormasyon kapag nakipag-ugnayan ka sa amin:

  • Isang detalyadong paglalarawan ng isyu

  • Ang job ID

  • Anumang kaugnay na mensahe ng error o code

Nakatuon kami sa pagbibigay sa iyo ng mabilis at epektibong suporta para matiyak na mayroon kang pinakamahusay na karanasan sa aming Qiskit Function.

Palagi kaming naghahanap ng paraan para mapabuti ang aming produkto at tinatanggap namin ang iyong mga mungkahi! Kung mayroon kang mga ideya kung paano namin mapapahusay ang aming mga serbisyo o mga feature na nais mong makita, pakipadala ang iyong mga kaisipan sa support@qedma.com.

Mga susunod na hakbang​