Releases: qBraid/pyqasm
Releases · qBraid/pyqasm
PyQASM 0.1.0
Release 0.1.0 (Dec 10, 2024)
Summary
Added
- Added support for
gphase
,toffoli
,not
,c3sx
andc4x
gates (#86) - Added a
remove_includes
method toQasmModule
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 thepre_build.sh
script. (#99)
Deprecated
Removed
Fixed
- Fixed bugs in implementations of
gpi2
andprx
gates (#86)
Dependencies
Full Changelog:
PyQASM 0.1.0-alpha
Release 0.1.0-alpha (Nov 28, 2024)
Summary
Added
- Added a
dumps
andformatted_qasm
method to theQasmModule
class to allow for the conversion of aQasmModule
object to a string representation of the QASM code (#71) - Added the
populate_idle_qubits
method to theQasmModule
class to populate idle qubits with anid
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 anexternal_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
, anddumps
functions to thepyqasm
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 aQasmModule
object contains barriers (#85) - Added
pyqasm.cli
module withtyper
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 theQasmModule
class to only accept anopenqasm3.ast.Program
object as input (#71) - Changed
DepthNode
,QubitDepthNode
,ClbitDepthNode
, andVariable
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
redundantKeyError
handling with loop (#79) - The
load
function has been renamed toloads
andload
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
topyqasm.linalg_cy
with ~60% speedup - Migrated
pyqasm.linalg._so4_to_so2()
to topyqasm.linalg_cy
with ~5% speedup
- Migrated
- 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 theQasmModule
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
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 theQasmModule
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 theQasmModule
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 theQasm2Module
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
andpyqasm.validate.py
intopyqasm.entrypoint.py
with newpyqasm.load()
function which returns aQasm3Module
(#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
andvalidate
functions. Introduced a newload
function that returns aQasmModule
object, which can be used to then callunroll
andvalidate
. Also added methods likeremove_measurements
,remove_barriers
,has_measurements
anddepth
to theQasmModule
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 amodules
subpackage which contains theQasmModule
,Qasm2Module
andQasm3Module
classes (#62)
Deprecated
Removed
Fixed
- Bug in initial sizes of classical registers.
bit c;
was being initialized with size32
instead of1
(#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 typebit
(#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
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 frompyqasm.elements.Qasm3Module
tostr
. 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
Release 0.0.1 (Oct 15, 2024)
Summary
Modified
- Update README.md by @ryanhill1 in #4
- Update README.md by @TheGupta2012 in #5
Added
- Add initial implementation by @TheGupta2012 in #3
- Add github workflows and templates by @TheGupta2012 in #6
New Contributors
- @TheGupta2012 made their first contribution in #3
Full Changelog: v0.0.0...v0.0.1
PyQASM 0.0.0
Release 0.0.0 (Oct 4, 2024)
Summary
Added
PRs Merged
- project setup by @ryanhill1 in #1
- workflows + release by @ryanhill1 in #2
New Contributors
- @ryanhill1 made their first contribution in #1
Full Changelog: https://github.com/qBraid/pyqasm/commits/v0.0.0