Skip to content

Latest commit

 

History

History
186 lines (136 loc) · 7.03 KB

README.md

File metadata and controls

186 lines (136 loc) · 7.03 KB

QSmell

QSmell is a tool for detecting quantum-based code smells in programs written in the Qiskit framework. As Qiskit v0.37.0 requires Python version >= v3.7.8, QSmell also requires Python v3.7.8.

If you use this tool for academic purposes, please cite it as

@misc{QSmellV001,
  author = {Chen, Qihong and Câmara, Rúben and Campos, José and Souto, André and Ahmed, Iftekhar},
  title = {{QSmell v0.0.1}},
  year = {2023},
  publisher = {GitHub},
  url = {https://github.com/jose/qsmell}
}

in case you only want to cite the associated paper, please cite it as

@inproceedings{ChenQSmell2023,
  author = {Chen, Qihong and Câmara, Rúben and Campos, José and Souto, André and Ahmed, Iftekhar},
  booktitle = {2023 IEEE/ACM 45th International Conference on Software Engineering (ICSE)},
  title = {{The Smelly Eight: An Empirical Study on the Prevalence of Code Smells in Quantum Computing}},
  year = {2023},
  volume = {},
  number = {},
  pages = {},
  keywords = {},
  doi = {},
  url = {},
  ISSN = {},
  month = {May},
}

Workflow

Depending on the smell metric, QSmell either performs a dynamic or a static analysis.

The smell metrics CG, ROC, LC, IM, IdQ, and IQ, which rely on accurate data as the set of qubits and/or the set of operations performed in the circuit, are computed using dynamic analysis. The other smell metrics, NC and LPQ, which do not rely on the quantum circuit but on the actions performed on the quantum circuit, are computed using static analysis. The latter does not handle common code as loops or track objects passed as arguments to other functions. Thus it is possible to evaluate it with static analysis. The former does not handle calls to methods that are not part of a quantum circuit object (e.g., transpile, Qiskit backends' methods), thus, it is necessary to analyze it dynamically.

Dynamic Analysis

To perform a dynamic analysis on a quantum program, QSmell takes as input an execution matrix, where each row represents a quantum or classical bit, each column represents a timestamp in the circuit, and each cell represents a quantum operation performed in the circuit.

Given the following running example (example.py)

# example.py
from qiskit import QuantumCircuit, QuantumRegister, Aer

reg = QuantumRegister(3, name='reg')
qc = QuantumCircuit(reg)
qc.x(reg[0])
for i in range(0, 2):
    qc.x(reg[i])
qc.x(reg[1])
qc.x(reg[0])
qc.x(reg[2])
qc.y(reg[1])

backend = Aer.get_backend('qasm_simulator')
qc = transpile(qc, backend, initial_layout=[3, 4, 2])
job = backend.run(qc)

one would have to manually inject the following piece code

from quantum_circuit_to_matrix import qc2matrix
qc2matrix(qc, output_file_path='example-matrix.csv')

adapt it, in case, e.g., the quantum circuit may not be named qc, and run it to generate the execution matrix. Note that the quantum_circuit_to_matrix module was built by us on top of Qiskit's API and is part of the QSmell distribution.

For this running example, the execution matrix is

             1 &   2 &   3
q-reg-0} & x() & x() & x()
q-reg-1} & x() & x() & y()
q-reg-2} & x() & x() &    

This manual step could not be automatized at the time of writing this document as different programs could be coded differently. For example, although qc is a standard variable name that holds a QuantumCircuit object, it might have been named differently, or it might be under a method of the program itself. For example, to get the QuantumCircuit object of the vqd program, one would have to invoke the construct_circuit method of the vqd class to retrieve its QuantumCircuit object.

Once the execution matrix has been generated to compute, e.g., the LC smell metric, QSmell first computes the maximum number of operations in any qubit (any row in the matrix). In the above example, such maximum is three in qubit q-reg-0, for example. It then performs a similar procedure to compute the maximum number of operations performed simultaneously (i.e., in the same timestamp/column). The maximum number of operations (i.e., three) are performed in the first and second columns. Finally, the LC metric is (1 - 0.03512)^{3 * 3} = 0.725.

Static Analysis

As the information of the quantum backend (see lines 14-16 of the running example) is not kept in the quantum circuit object itself, QSmell performs a static analysis for smell metrics NC and LPQ. It takes a source code .py file and analysis it using Python AST. To compute the LPQ smell metric for the running example, QSmell first finds all calls to the transpile method in the program's under analysis AST and then counts how many do not define the initial_layout parameter.

Installation

Installing and using QSmell is simple and straightforward. First, one should get its latest version from pip.

pip install qsmell # Not yet deployed

or from the tool's repository:

git clone https://github.com/jose/qsmell

and install QSmell's dependencies

pip install -r requirements.txt

and finally compile/install QSmell from it's source code

python3 setup.py install

Usage example

Given the following quantum program (example.py)

# example.py
from qiskit import QuantumCircuit, QuantumRegister, Aer

reg = QuantumRegister(3, name='reg')
qc = QuantumCircuit(reg)
qc.x(reg[0])
for i in range(0, 2):
    qc.x(reg[i])
qc.x(reg[1])
qc.x(reg[0])
qc.x(reg[2])
qc.y(reg[1])

backend = Aer.get_backend('qasm_simulator')
qc = transpile(qc, backend, initial_layout=[3, 4, 2])
job = backend.run(qc)

one could run QSmell as

qsmell \
  --smell-metric "ROC" \
  --input-file "example-matrix.csv" \
  --output-file "roc-smell-metric.csv"

which produces the following CSV file:

metric,value
ROC,2

To perform static analysis, or in other words, to compute the NC or LQP smell metrics, one could invoke QSmell on the source code under analysis as:

qsmell \
  --smell-metric "NC" \
  --input-file "example.py" \
  --output-file "nc-smell-metric.csv"

Command-line arguments

  -h, --help            show this help message and exit
  --version, -v         show program's version number and exit
  --smell-metric {CG,ROC,NC,LC,IM,IdQ,IQ,AQ,LPQ}, -s {CG,ROC,NC,LC,IM,IdQ,IQ,AQ,LPQ} Quantum smell metric to compute
  --input-file INPUT_FILE, -i INPUT_FILE Quantum program/circuit to analyse
  --output-file OUTPUT_FILE, -o OUTPUT_FILE Output file

Publications

  • "The Smelly Eight: An Empirical Study on the Prevalence of Code Smells in Quantum Computing" Qihong Chen, Rúben Câmara, José Campos, André Souto, and Iftekhar Ahmed, ICSE 2023.

More publications

License

MIT License, see LICENSE.md for more information.