Source code for qbraid.transpiler.conversions.openqasm3.conversions_qasm

# Copyright (C) 2023 qBraid
#
# This file is part of the qBraid-SDK
#
# The qBraid-SDK is free software released under the GNU General Public License v3
# or later. You can redistribute and/or modify it under the terms of the GPL v3.
# See the LICENSE file in the project root or <https://www.gnu.org/licenses/gpl-3.0.html>.
#
# THERE IS NO WARRANTY for the qBraid-SDK, as per Section 15 of the GPL v3.

"""
Module containing OpenQASM conversion function

"""
import os

import openqasm3

from qbraid.programs.inspector import get_qasm_version
from qbraid.programs.qasm_qelib1 import _decompose_rxx_instr

QASMType = str


def _get_qasm3_gate_defs() -> str:
    """Helper function to get openqasm 3 gate defs from .qasm file"""
    current_dir = os.path.dirname(os.path.abspath(__file__))
    qelib_qasm = os.path.join(current_dir, "qelib_qasm3.qasm")
    with open(qelib_qasm, mode="r", encoding="utf-8") as file:
        gate_defs = file.read()
    return gate_defs


def _build_qasm_3_reg(line: str, qreg_type: bool) -> QASMType:
    """Helper function to build openqasm 3 register statements

    Args:
        line (str): openqasm 2  regdecl statement
        qreg_type (bool): whether a qreg or creg type statement

    Returns:
        str : openqasm 3 qubits / bits declaration
    """
    reg_keyword_len = 4
    line = line[reg_keyword_len:]
    elements = line.split("[")
    reg_name = elements[0].strip()
    reg_size = elements[1].split("]")[0].strip()
    result = "qubit" if qreg_type else "bit"
    result += f"[{reg_size}] {reg_name};\n"
    return result


def _build_qasm_3_measure(line: str) -> QASMType:
    """Helper function to build openqasm 3 measure string

    Args:
        line (str): openqasm 2 measure statement

    Returns:
        str:  openqasm 3 measure statement
    """
    measure_keyword_len = 7
    line = line[measure_keyword_len:]
    elements = line.split("->")
    qubits_name = elements[0].replace(" ", "")
    bits_name = elements[1].split(";")[0].replace(" ", "")

    return f"{bits_name} = measure {qubits_name};\n"


def _convert_line_to_qasm3(line: str) -> QASMType:
    """Function to change an openqasm 2 line to openqasm 3

    Args:
        line (str): an openqasm 2 line

    Returns:
        str: corresponding openqasm 3 line
    """
    line = line.lstrip()
    if line.startswith("OPENQASM"):
        return ""
    if "qelib1.inc" in line:
        return ""
    if line.startswith("qreg"):
        return _build_qasm_3_reg(line, qreg_type=True)
    if line.startswith("creg"):
        return _build_qasm_3_reg(line, qreg_type=False)
    if line.startswith("u("):
        return line.replace("u(", "U(")
    if line.startswith("rxx("):
        return _decompose_rxx_instr(line)
    if line.startswith("measure"):
        return _build_qasm_3_measure(line)
    if line.startswith("opaque"):
        # as opaque is ignored by openqasm 3 add it as a comment
        return "// " + line + "\n"
    return line + "\n"


[docs] def qasm2_to_qasm3(qasm_str: str) -> QASMType: """Convert a OpenQASM 2.0 string to OpenQASM 3.0 string Args: qasm_str (str): OpenQASM 2.0 string Returns: str: OpenQASM 3.0 string """ qasm_version = get_qasm_version(qasm_str) if not qasm_version == "qasm2": raise ValueError("Invalid OpenQASM 2.0 string") qasm3_str = "OPENQASM 3.0;\ninclude 'stdgates.inc';" gate_defs = _get_qasm3_gate_defs() for line in gate_defs: qasm3_str += line for line in qasm_str.splitlines(): line = _convert_line_to_qasm3(line) qasm3_str += line return qasm3_str
[docs] def qasm3_to_openqasm3(qasm_str: str) -> openqasm3.ast.Program: """Loads an openqasm3.ast.Program from an OpenQASM 3.0 string Args: qasm_str (str): OpenQASM 3.0 string Returns: openqasm3.ast.Program: OpenQASM 3.0 AST program """ return openqasm3.parse(qasm_str)
[docs] def openqasm3_to_qasm3(program: openqasm3.ast.Program) -> str: """Dumps openqasm3.ast.Program to an OpenQASM 3.0 string Args: program (openqasm3.ast.Program): OpenQASM 3.0 AST program Returns: str: OpenQASM 3.0 string """ return openqasm3.dumps(program)