Skip to content

Releases: qBraid/pyqasm

PyQASM 0.1.0

10 Dec 05:28
d8fc16b
Compare
Choose a tag to compare

Release 0.1.0 (Dec 10, 2024)

Summary

Added

  • Added support for gphase, toffoli, not, c3sx and c4x gates (#86)
  • Added a remove_includes method to QasmModule to remove include statements from the generated QASM code (#100). Usage example -
In [1]: from pyqasm import loads

In [2]: module = loads(
   ...: """OPENQASM 3.0;
   ...: include "stdgates.inc";
   ...: include "random.qasm";
   ...: 
   ...: qubit[2] q;
   ...: h q;
   ...: """)

In [3]: module.remove_includes()
Out[3]: <pyqasm.modules.qasm3.Qasm3Module at 0x10442b190>

In [4]: from pyqasm import dumps

In [5]: dumps(module).splitlines()
Out[5]: ['OPENQASM 3.0;', 'qubit[2] q;', 'h q;']

Improved / Modified

  • Refactored the initialization of QasmModule to remove default include statements. Only user supplied include statements are now added to the generated QASM code (#86)
  • Update the pre-release.yml workflow to multi-platform builds. Added the pre-release version bump to the pre_build.sh script. (#99)

Deprecated

Removed

Fixed

  • Fixed bugs in implementations of gpi2 and prx gates (#86)

Dependencies

Full Changelog:

PyQASM 0.1.0-alpha

28 Nov 08:24
9b0c198
Compare
Choose a tag to compare
PyQASM 0.1.0-alpha Pre-release
Pre-release

Release 0.1.0-alpha (Nov 28, 2024)

Summary

Added

  • Added a dumps and formatted_qasm method to the QasmModule class to allow for the conversion of a QasmModule object to a string representation of the QASM code (#71)
  • Added the populate_idle_qubits method to the QasmModule class to populate idle qubits with an id gate (#72)
  • Added gate definitions for "c3sqrtx", "u1", "rxx", "cu3", "csx", "rccx" , "ch" , "cry", "cp", "cu", "cu1", "rzz" in maps.py (#74)
  • Added support for skipping the unrolling for externally linked gates. The QasmModule.unroll() method now accepts an external_gates parameter which is a list of gate names that should not be unrolled (#59). Usage -
In [30]: import pyqasm

In [31]: qasm_str = """OPENQASM 3.0;
    ...:     include "stdgates.inc";
    ...:     gate custom q1, q2, q3{
    ...:         x q1;
    ...:         y q2;
    ...:         z q3;
    ...:     }
    ...:
    ...:     qubit[4] q;
    ...:     custom q[0], q[1], q[2];
    ...:     cx q[1], q[2];"""

In [32]: module = pyqasm.loads(qasm_str)

In [33]: module.unroll(external_gates= ["custom"])

In [34]: pyqasm.dumps(module).splitlines()
Out[34]:
['OPENQASM 3.0;',
 'include "stdgates.inc";',
 'qubit[4] q;',
 'custom q[0], q[1], q[2];',
 'cx q[1], q[2];']
  • Major Change: Added the load, loads, dump, and dumps functions to the pyqasm module to allow for the loading and dumping of QASM code (#76). Usage -
In [18]: import pyqasm

In [19]: qasm_str = """OPENQASM 3.0;
    ...:     include "stdgates.inc";
    ...:     qreg q1[2];
    ...:     qubit[2] q2;"""

In [20]: module = pyqasm.loads(qasm_str)

In [21]: print(pyqasm.dumps(module))
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q1;
qubit[2] q2;


In [22]: file_path = "test.qasm"

In [23]: pyqasm.dump(module, file_path)

In [24]: module = pyqasm.load(file_path)

In [25]: print(pyqasm.dumps(module))
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q1;
qubit[2] q2;
  • Added definitions for various gates in maps.py and tests for qasm formatting functions of the qbraid-sdk (#82, #84)
  • Added pyqasm.accelerate module to hold .pyx files with Cython-based optimizations for computationally intensive functions (#83)
  • Added has_barriers method for checking if a QasmModule object contains barriers (#85)
  • Added pyqasm.cli module with typer integration to enable using pyqasm as a command-line tool (#87)
$ pip install 'pyqasm[cli]'
$ pyqasm --help
Usage: pyqasm [OPTIONS] COMMAND [ARGS]...
$ pyqasm --version
pyqasm/0.1.0a1
$ pyqasm validate tests/cli/resources
tests/cli/resources/invalid1.qasm: error: Index 2 out of range for register of size 1 in qubit [validation]
Found errors in 1 file (checked 3 source files)
$ pyqasm validate tests/cli/resources --skip tests/cli/resources/invalid1.qasm
Success: no issues found in 2 source files

Improved / Modified

  • Changed the __init__ method for the QasmModule class to only accept an openqasm3.ast.Program object as input (#71)
  • Changed DepthNode, QubitDepthNode, ClbitDepthNode, and Variable to dataclasses. __repr__ method is therefore handled automatically and you don't need all of the redundant private / public attribute and setters (#79)
  • Simplified map_qasm_op_to_callable redundant KeyError handling with loop (#79)
  • The load function has been renamed to loads and load is now used to load a QASM file. QasmModule.dumps() has been replaced with __str__ method (#76)
  • Experimental Cython integration: (#83)
    • Migrated pyqasm.linalg._kronecker_factor to pyqasm.linalg_cy with ~60% speedup
    • Migrated pyqasm.linalg._so4_to_so2() to to pyqasm.linalg_cy with ~5% speedup
  • Changed source code directory from ./pyqasm to ./src/pyqasm to prevents conflicts between the local source directory and the installed package in site-packages, ensuring Python's module resolution prioritizes the correct version. Required for local testing with new Cython build step (#83)
  • Updated the build process for pyqasm due to Cython integration. Wheels are now built for each platform and uploaded to PyPI along with the source distributions (#88)

Deprecated

Removed

  • Removed the from_program method from the QasmModule class (#71)
  • QasmModule.formatted_qasm() method has been removed (#76)

Fixed

  • Updated docs custom CSS used for sphinx to make version stable/latest drop-down visible. Previously was set white so blended into background and wasn't visible. (#78)
  • Fixed bug in pyqasm.linalg.so_bidiagonalize() in final dot product order (#83)

Dependencies

New Contributors

Full Changelog: v0.0.3...v0.1.0-alpha

PyQASM 0.0.3

06 Nov 13:34
9a9000f
Compare
Choose a tag to compare

Release 0.0.3 (Nov 6, 2024)

Summary

Added

  • Dependabot configuration file (#37)
  • Added support for QASM2 program validation and unrolling (#46)
  • Added better typing to linalg module + some tests (#47)
  • Added a remove_idle_qubits method to the QasmModule class which can be used to remove idle qubits from a quantum program (#58). Usage is as follows -
In [3]: import pyqasm
   ...: qasm_str = """OPENQASM 3.0;
   ...:      gate custom q1, q2, q3{
   ...:          x q1;
   ...:          y q2;
   ...:          z q3;
   ...:      }
   ...:      qreg q1[2];
   ...:      qubit[2] q2;
   ...:      qubit[3] q3;
   ...:      qubit q4;
   ...:      qubit[5]   q5;
   ...:
   ...:      x q1[0];
   ...:      y q2[1];
   ...:      z q3;"""
   ...: module = pyqasm.load(qasm_str)
   ...: module.validate()
   ...:

In [4]: module.num_qubits
Out[4]: 13

In [5]: module.remove_idle_qubits()
Out[5]: <pyqasm.modules.Qasm3Module at 0x1052364b0>

In [6]: module.num_qubits
Out[6]: 5

In [7]: module.unrolled_qasm.splitlines()
Out[7]:
['OPENQASM 3.0;',
 'include "stdgates.inc";',
 'qubit[1] q1;',
 'qubit[1] q2;',
 'qubit[3] q3;',
 'x q1[0];',
 'y q2[0];',
 'z q3[0];',
 'z q3[1];',
 'z q3[2];']
  • Implemented the reverse_qubit_order method to the QasmModule class which can be used to reverse the order of qubits in a quantum program (#60). Usage is as follows -
In [3]: import pyqasm

In [4]: qasm3_str = """
   ...:     OPENQASM 3.0;
   ...:     include "stdgates.inc";
   ...:     qubit[2] q;
   ...:     qubit[4] q2;
   ...:     qubit q3;
   ...:     bit[1] c;
   ...:
   ...:     cnot q[0], q[1];
   ...:     cnot q2[0], q2[1];
   ...:     x q2[3];
   ...:     cnot q2[0], q2[2];
   ...:     x q3;
   ...:     c[0] = measure q2[0];
   ...:     """

In [5]: module = pyqasm.load(qasm3_str)

In [6]: module.reverse_qubit_order()
Out[6]: <pyqasm.modules.Qasm3Module at 0x105bc9ac0>

In [7]: module.unrolled_qasm.splitlines()
Out[7]:
['OPENQASM 3.0;',
 'include "stdgates.inc";',
 'qubit[2] q;',
 'qubit[4] q2;',
 'qubit[1] q3;',
 'bit[1] c;',
 'cx q[1], q[0];',
 'cx q2[3], q2[2];',
 'x q2[0];',
 'cx q2[3], q2[1];',
 'x q3[0];',
 'c[0] = measure q2[3];']
  • Added the to_qasm3() method to the Qasm2Module class which can be used to convert a QASM2 program to QASM3 (#62). Usage is as follows -
In [7]: import pyqasm

In [8]: qasm2_str = """
  ...:      OPENQASM 2.0;
  ...:      include "qelib1.inc";
  ...:      qreg q[2];
  ...:      creg c[2];
  ...:      h q[0];
  ...:      cx q[0], q[1];
  ...:      measure q -> c;
  ...:      """

In [9]: module = pyqasm.load(qasm2_str)

In [10]: module.to_qasm3(as_str = True).splitlines()
Out[10]:
['OPENQASM 3.0;',
'include "stdgates.inc";',
'qubit[2] q;',
'bit[2] c;',
'h q[0];',
'cx q[0], q[1];',
'c = measure q;']

In [11]: qasm3_mod = module.to_qasm3()

In [12]: qasm3_mod
Out[12]: <pyqasm.modules.qasm3.Qasm3Module at 0x107854ad0>

Improved / Modified

  • Improved qubit declaration semantics by adding check for quantum registers being declared as predefined constants (#44)
  • Updated pre-release scripts + workflow (#47)
  • Moved pylint config from pyproject to rcfile, reduced disabled list, and moved disable flags to specific areas where applicable instead of over entire files (#47)
  • Consolidated duplicate code from pyqasm.unroller.py and pyqasm.validate.py into pyqasm.entrypoint.py with new pyqasm.load() function which returns a Qasm3Module (#47)
  • Updated examples in README.md to show outputs and explain in more detail what's happening in each example (#47)
  • Updated the handling of qasm version string by forcing it to be x.0 (#48)
  • Major Update: Changed the API for the unroll and validate functions. Introduced a new load function that returns a QasmModule object, which can be used to then call unroll and validate. Also added methods like remove_measurements, remove_barriers, has_measurements and depth to the QasmModule class (#49). Usage is as follows -
In [1]: import pyqasm

In [2]: qasm_str = """OPENQASM 3.0;
   ...:     gate custom q1, q2, q3{
   ...:         x q1;
   ...:         y q2;
   ...:         z q3;
   ...:     }
   ...:     qreg q1[2];
   ...:     qubit[2] q2;
   ...:     qubit[3] q3;
   ...:     qubit q4;
   ...:     qubit[5]   q5;
   ...:     qreg qr[3];
   ...:
   ...:     x q1[0];
   ...:     y q2[1];
   ...:     z q3;
   ...:
   ...:
   ...:     qubit[3] q6;
   ...:
   ...:     cx q6[1], q6[2];"""

In [3]: module = pyqasm.load(qasm_str)

In [4]: module.num_qubits
Out[4]: 19

In [5]: module.num_clbits
Out[5]: 0

In [6]: module.validate()

In [7]: module.unroll()

In [8]: module.unrolled_qasm.splitlines()
Out[8]:
['OPENQASM 3.0;',
 'include "stdgates.inc";',
 'qubit[2] q1;',
 'qubit[2] q2;',
 'qubit[3] q3;',
 'qubit[1] q4;',
 'qubit[5] q5;',
 'qubit[3] qr;',
 'x q1[0];',
 'y q2[1];',
 'z q3[0];',
 'z q3[1];',
 'z q3[2];',
 'qubit[3] q6;',
 'cx q6[1], q6[2];']

In [9]: module.has_measurements()
Out[9]: False

In [10]: module.remove_measurements()
Out[10]: <pyqasm.modules.Qasm3Module at 0x107406540>

In [11]: module.depth()
Out[11]: 1

Users can also choose to pass an in_place=False argument to the methods above and get a new QasmModule object with the applied changes -

In [1]: import pyqasm

In [2]: qasm_str = """OPENQASM 3.0;
   ...:     gate custom q1, q2, q3{
   ...:         x q1;
   ...:         y q2;
   ...:         z q3;
   ...:     }
   ...:     qreg q1[2];
   ...:     qubit[2] q2;
   ...:     qubit[3] q3;
   ...:     qubit q4;
   ...:     qubit[5]   q5;
   ...:     qreg qr[3];
   ...:
   ...:     x q1[0];
   ...:     y q2[1];
   ...:     z q3;"""

In [3]: module = pyqasm.load(qasm_str)

In [4]: module.validate()

In [5]: module_copy = module.remove_measurements(in_place=False)
  • Restructured the pyqasm package to have a modules subpackage which contains the QasmModule, Qasm2Module and Qasm3Module classes (#62)

Deprecated

Removed

Fixed

  • Bug in initial sizes of classical registers. bit c; was being initialized with size 32 instead of 1 (#43)
  • Fixed bug in the handling of classical register type. Whenever a bit was referenced in an expression, it was treated as a scalar when it should be treated as an element of a 1D array with type bit (#44)

Dependencies

  • Update sphinx-autodoc-typehints requirement from <2.5,>=1.24 to >=1.24,<2.6 (#38)
  • Update sphinx requirement from <8.1.0,>=7.3.7 to >=7.3.7,<8.2.0 (#39)
  • Update sphinx-rtd-theme requirement from <3.0.0,>=2.0.0 to >=2.0.0,<4.0.0 (#40)

Full Changelog: v0.0.2...v0.0.3

PyQASM 0.0.2

21 Oct 12:18
8e5111e
Compare
Choose a tag to compare

Release 0.0.2 (Oct 21, 2024)

Summary

Added

  • Sphinx docs and examples added for pyqasm (#20)
  • qBraid header check enabled in format action(#29)
  • Integrated code coverage with codecov (#30)

Improved / Modified

  • Housekeeping updates involving codeowners, workflows, pyproject, and readme (#16)
  • Fixed parsing of compile-time constants for register sizes. Statements like const int[32] N = 3; qubit[N] q; are now supported (#21).
  • Update project README.md (#22)
  • Updated sphinx docs page (#26)
  • Major Change: The default type for pyqasm.unroller.unroll has been changed from pyqasm.elements.Qasm3Module to str. This change is backward-incompatible and will require users to update their code. The following code snippet demonstrates the change -
from pyqasm.unroller import unroll
qasm_str = """
OPENQASM 3;
qubit[3] q;
h q;
"""

# Old way : The default type for unroll was pyqasm.elements.Qasm3Module
program = unroll(qasm_str, as_module=True)
unrolled_qasm_old = program.unrolled_qasm

# New way : The default type for unroll is now str
unrolled_qasm_new = unroll(qasm_str)

To force the return type to be pyqasm.elements.Qasm3Module, users can set the as_module parameter to True as shown above to update their code.

Deprecated

Removed

Fixed

  • Issue with aliasing of qubits was fixed where aliased qubits were referenced with non-aliased qubits in a quantum gate (#14). The following program is now supported -
OPENQASM 3;
include "stdgates.inc";
qubit[4] q;
let alias = q[0:2];
cx alias[1], q[2];
  • Issue with subroutines, when return keyword was absent, was fixed in (#21)

Full Changelog: v0.0.1...v0.0.2

PyQASM 0.0.1

15 Oct 06:17
0a43176
Compare
Choose a tag to compare

Release 0.0.1 (Oct 15, 2024)

Summary

Modified

Added

New Contributors

Full Changelog: v0.0.0...v0.0.1

PyQASM 0.0.0

04 Oct 18:30
a5e32ff
Compare
Choose a tag to compare

Release 0.0.0 (Oct 4, 2024)

Summary

Added

  • Setup basic project/repo template (#1)
  • Configured PyPI workflows (#2)

PRs Merged

New Contributors

Full Changelog: https://github.com/qBraid/pyqasm/commits/v0.0.0