munich-quantum-toolkit / munich-quantum-toolkit/qmap

🐛 Crash when running qmap.optimize_clifford() for large clifford circuits integrated with `qiskit`'s `TransformationPass`

Open
#670 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
146
Forks
41
Avg merge
6h 47m
Merged PRs (30d)
45

Description

System Information
  • OS
NAME="Linux Mint"
VERSION="22.1 (Xia)"
ID=linuxmint
ID_LIKE="ubuntu debian"
PRETTY_NAME="Linux Mint 22.1"
VERSION_ID="22.1"
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.linuxmint.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
VERSION_CODENAME=xia
UBUNTU_CODENAME=noble
  • mqt-qmap:3.1.3
  • Python version: 3.12.3
  • Dependencies:
dependencies = [
    "cirq-core>=1.4.1,<2.0.0",
    "mitiq>=0.45.1",
    "mqt-qmap>=3.1.3",
    "ply>=3.11,<4.0.0",
    "pytket>=1.40.0,<3.0.0",
    "qbraid>=0.9.3,<1.0.0",
    "qiskit>=1.4.2,<3.0.0",
    "qiskit-qasm3-import>=0.5.1,<1.0.0",
]
Bug Description

My PC crash. I expect the script would be running normally.

Steps to Reproduce
  1. Setup env:
    For ease, clone the following repo
    https://github.com/unitaryfoundation/ucc.git
    and https://github.com/unitaryfoundation/ucc-bench. Then cd to the directories in different windows.

In ucc dir, install uv https://docs.astral.sh/uv/getting-started/installation/
Then run

uv sync --all-extras --all-groups
uv add mqt-qmap
uv sync --all-extras --all-groups

In ucc-bench, run

uv sync --all-groups
  1. Create the following script
import os

from qbraid.transpiler import transpile as translate
from qiskit import transpile as qiskit_transpile

def random_clifford_circuit(num_qubits, seed=12345):
    """Generate a random clifford circuit
    Parameters:
        num_qubits (int): Number of qubits
        seed (int): Optional. Seed the random number generator, default=12345

    Returns:
        QuantumCircuit: Clifford circuit
    """
    # This code is used to generate the QASM file
    from qiskit.circuit.random import random_clifford_circuit

    gates = ["cx", "cz", "cy", "swap", "x", "y", "z", "s", "sdg", "h"]
    qc = random_clifford_circuit(
        num_qubits,
        gates=gates,
        num_gates=200 * num_qubits * num_qubits,
        seed=seed,
    )
    return qc



def write_qasm(
    circuit,
    circuit_name,
    version="2",
    basis_gates=[],
    folder="../qasm_circuits",
):
    qiskit_circuit = translate(circuit, "qiskit")
    if basis_gates:
        decomp_circuit = qiskit_transpile(
            qiskit_circuit, basis_gates=basis_gates, optimization_level=0
        )
    else:
        decomp_circuit = qiskit_circuit

    # Generate QASM string
    qasm_string = translate(decomp_circuit, "qasm" + version)

    # Get the absolute path of the current script
    script_dir = os.path.dirname(os.path.abspath(__file__))

    # Create the absolute path for the folder where QASM files will be saved
    abs_folder = os.path.abspath(os.path.join(script_dir, folder))

    # Construct the filename with the given circuit name and version
    filename = os.path.join(abs_folder, f"qasm{version}/ucc/{circuit_name}")

    # Append basis gates to the filename if they are provided
    if basis_gates:
        filename += f"_basis_{'_'.join(basis_gates)}"

    os.makedirs(os.path.dirname(filename), exist_ok=True)

    with open(filename + ".qasm", "w") as file:
        file.write(qasm_string)

circuit = random_clifford_circuit(10)
filename = f"random_clifford_circuit_N{10}"

write_qasm(circuit, circuit_name=filename, version="2")

Then run this uv run python <path-to-the-above-script>
Add the following content to benchmarks/scripts/run_benchmarks.py

from qiskit import QuantumCircuit
from qiskit.transpiler import PassManager, TransformationPass
from qiskit.converters import dag_to_circuit, circuit_to_dag
from qiskit.dagcircuit import DAGCircuit
from mqt import qmap

# Define the custom optimization pass
class QMAPCliffordOptimization(TransformationPass):
    def run(self, dag):
        circuit = dag_to_circuit(dag)
        circ_opt, results = qmap.optimize_clifford(circuit)
        dag_opt = circuit_to_dag(circ_opt)
        return dag_opt

# Function to count two-qubit gates
def count_gates(circuit: QuantumCircuit):
    return circuit.num_nonlocal_gates()

# Load your circuit from a QASM file
qasm_file = 'benchmarks/circuits/ucc/random_clifford_circuit_N10.qasm' # The path to the file
circuit = QuantumCircuit.from_qasm_file(qasm_file)

# Apply the optimization pass
pm = PassManager([QMAPCliffordOptimization()])
optimized_circuit = pm.run(circuit)  # Pass the QuantumCircuit directly

# Count gates before and after optimization
original_gate_count = count_gates(circuit)
optimized_gate_count = count_gates(optimized_circuit)

print(f"Original two-qubit gate count: {original_gate_count}")
print(f"Optimized two-qubit gate count: {optimized_gate_count}")

Run uv run python benchmarks/scripts/run_benchmarks.py
3. Gate counts should be printed, but the system is crashed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the crash with the script and benchmarks/scripts/run_benchmarks.py, focusing on the qmap.optimize_clifford() call inside QMAPCliffordOptimization.run. Check how the circuit is passed through Qiskit's TransformationPass integration and determine why the large circuit crashes instead of printing both gate counts. Done means the benchmark completes without crashing and prints the original and optimized counts.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.