Changelogs » Pyqrack

PyUp Safety actively tracks 362,670 Python packages for vulnerabilities and notifies you when to upgrade.



This release fixes a bug in the underlying `Qrack::QUnit::AntiCZ()` gate method, which might have caused issues with correctness of sampling statistics, depending on how the gate was engaged.


This binary(-only) update greatly improves the efficiency of measurement sampling in cases, such as particularly when collecting a single sample with `measure_shots()`.


Measurement sampling execution speed has been greatly improved, for low-entanglement systems with Schmidt decomposition layer, and for hybrid-stabilizer layer. (The API has not changed.)


QrackSimulator()` constructor arguments have been fixed. `ctypes` does not necessarily complain or throw exception if a bound method signature doesn't correspond to that of a Python call, and this led me to originally call the wrong initialization method for specifying layer options.


Two bugs were fixed in the Qrack static and shared libraries:
  - PhaseParity() gate gave incorrect results, depending on optimization layers, in the static library
  - Boolean gates in the shared library did not correctly map simulator qubit labels
  Additionally, importing `setuptools` instead of `distutils.core` in the `none-any` wheel seems to fix its compatibility with Mac systems, and probably more generally.


The shared library was accidentally holding onto potentially significant garbage due to unnecessary use of strong `shared_ptr` references as map keys. Stability has been improved in situations where many simulators are allocated and freed.


v0.7.0 adds the option to disable many of Qrack's optimization layers, in the system-specific optimal layer stack, (which is bimodal, depending on the presence/absence of OpenCL devices). For many specific circuits of interest, significant additional performance can be gained by disabling one or more Qrack layer stacks, if one knows the characteristics of their workload, as regards the attempted optimizations in Qrack.
  (However, the default case, with _all_ optimizations layers on, is designed for best general performance based upon developer experimentation with realistic and/or high-entanglement universal circuits. It is expected that users will most commonly best benefit from leaving all optimization layers on by default, and not considering v0.7.0 options at all, without a reason.)


This release only adds support for ARM64 Linux systems. No changes to the binary source implementation or API have been made since v0.5.3.
  I'm testing on a Raspberry Pi 4 with beta version 64-bit operating system, and, despite having a rather long list of platform tags for wheels that the system _should_ be compatible with, `pip` on this system only seems to accept `none-any` wheels. This doesn't prevent us from offering a `none-any` wheel that is compatible with 64-bit Raspberry Pi OS, but it does force users to use the non-specific `none-any` wheel, which includes _all_ platform binaries we support, significantly increasing the size of download and installation for the package. (The difference is _significant_, as a percentage of package size with only ARM64 binary, but the entire `none-any` wheel file is still only ~8 MB.)
  Note also that the ARM64 binary here is theoretically OpenCL-ready, without modification, for systems with one or more ICDs, as are all binaries in PyQrack.


This fixes a PhaseParity edge case.
  See (Apologies again for the rapid-fire release updates. Note that if your circuit didn't raise exception with v0.5.2, you weren't affected by the PhaseParity edge case I'm struggling with, here.)


There was a bugged edge case in `QPager::PhaseParity()`, when the qubit `mask` contained _only_ "global qubits." This is fixed by v0.5.2.


PyZX includes a "PhaseParity" gate within its internal set of gates. This gate can be implemented quite efficiently, over any qubit width, at the simulator level. The Qrack binaries have been updated to efficiently implement this gate, and the native implementation can be called directly via a `QrackSimulator` instance.


This debugs PyZX `Circuit` graph support. (With this work out of the experimental phase, I expect v0.5.0 to be the first version to truly support PyZX `Circuit` graphs.)


sim = QrackSimulator(pyzxCircuit=c)
  where `c` is a PyZX circuit object. The circuit will automatically be simulated in the constructed `QrackSimulator` instance. This also allows loading from QASM and other intermediate representations supported by PyZX.
  Also, reversing the state of v0.4.5, the none/any wheel includes _all_ available binaries from the author, while building from source assumes an installation of the underlying Qrack library from source.


This release refactors the concurrency handling in the underlying Qrack shared library interface binary. A "meta-" mutex synchronizes shared library simulator management by STL containers, as previously. However, the "meta-" mutex is now released once a new **`QrackSimulator`-specific mutex** is locked, for operations limited in scope to dispatching simulator methods. Hopefully, with (mostly intuitive) Python threading best practices, this reduces contention and increases stability in Python environments performing asynchronous threads of operations on different simulators.
  It is important to note, PyQrack and Qrack will attempt to distribute new demand for simulation RAM to every available device in descending order of immediate device load, with the (environment-variable-selectable) default device preferred in load balancing contest ties. It is also possible, but not typically recommended, to control via environment variable whether PyQrack reactively redistributes unbalanced loads, instead of only redistributing through balancing **new** demand. (In the case of load-redistribution being activated, the device any load is currently on is preferred in case of redistribution ties, before default device.) Also, at a very low level, argument hooks for OpenCL kernels are device-specific, and cause thread contention on the combination of device and kernel call, like the kernel for the general single qubit gate, underlying many named single qubit gate methods. **See the vm6502q/qrack repository README for more information about these environment variables.**
  The none/any wheel is `main` branch. However, we now package all wheel binaries together in the build-from-source distribution on PyPi, to maximize device market share coverage for the sake of users.


One of the OpenCL kernels in the underlying Qrack library was redundant with OpenCL v1.1 APIs. This kernel has been cut. (Compiled OpenCL program size can be a limited resource, so it is important to generally minimize program size, depending on trade-offs with performance, but there is no such trade-off in this case.)
  Also, Linux shared libraries are now loaded according their local links (or "shortcuts"). This makes it possible, in the future, on Linux x86_64 and other systems, to properly alias shared libraries as per the conventions of the GNU linker.


This adds binaries that will automatically fall back from OpenCL to pure C++11 CPU-only simulation, if 0 OpenCL devices are present in the system. Also, an ARMv7 binary/wheel has been tested and is now fully supported.
  Since the available wheels comprise the full extent of the PyQrack developer's ability to compile and support binaries, and the vast majority of systems that can use these binaries will select the appropriate wheels, `none_any` default wheel will match `main` branch and assume that vm6502q/qrack will be built and installed custom on the desired system.


Hypothetical PyQrack builds have been cut, for which vm6502q/qrack builds but PyQrack hasn't or can't be tested. Momentarily, this only leaves us with x86_64 builds across Linux, Mac, and Windows, and 32-bit x86 builds for Windows. Every one of these variants has a separate wheel with a minimum of unnecessary binaries.


This adds a wheel specifically for Linux x86_64 systems that contains only the binaries necessary for that platform. In the near future, the same will be done for all systems we intend to support.
  Also, the binary previously categorized as "ARM64" appears not to actually be for that platform. At least, it was compiled on a system presumed to be ARM64, but that system actually resolves a platform name of "armv7l". The binary selection has been updated accordingly.


This adds additional optimized gates to the API, so as to help expose all useful Qrack optimization directly to Python.


The `mcu` gate should internally cast its unitary angle parameters to `c_double`. This release adds the appropriate casts.
  The `QrackSimulator()` `cloneSid` named argument didn't work. If the user attempted to clone, the `__del__` method tried to delete a simulator that didn't exist, within the shared library layer. This update fixes these bugs, and it does not require any shared library update.


This release updates the Qrack binaries for better default QUnitMulti device scheduling behavior, on systems with multiple OpenCL devices installed. This also adds a new environment variable to the underlying Qrack binary, `QRACK_ENABLE_QUNITMULTI_REDISTRIBUTE`, explained in the vm6502q/qrack README file. (Default behavior, without modifying the environment variables in use, should tend to work best, on most consumer home systems.)


The single call in the Qrack library to flush any OpenCL queue, immediately after every gate kernel dispatch, was returning an unspecified OpenCL error under high load. By simply removing this one queue flush call, no other errors arise, where we check _every_ OpenCL call for error codes. (This therefore appears to be a driver bug, but the behavior might be practically expected, if our gate kernels dispatch and flush very quickly.)


Qrack's optimized "arithmetic logic unit" has been wrapped for PyQrack.
  Some errata: This might be not the exact build that went to PyPi, for 0.3.0. However, after accidentally publishing a transient artifact, I tested that build for 2 known (negative) issues, and found that neither were issues for the version on PyPi:
  1. `mtrx` custom gates should be cast to floats, when broken into real and imaginary components from complex numbers. (This would raise a warning in SimulaQron tests, if not fixed in the package, but the package does not raise this warning.)
  2. Qrack binaries should have been updated to actually contain the ALU method wrappers. (The package correctly runs Grover's search on a lookup table, so its binaries must contain these methods. I only generated one new set of binaries.)
  There was a change to the README that I wanted to include, but it isn't critical. The labor-intensive part of any PyQrack release is building all Qrack binaries, which are already built correctly for 0.3.x release, so, if an issue arises, It'll take 15 minutes to iterate a patch. Please continue to feel free to open issue tickets.


This adds the Schmidt decomposition methods `Compose()`, `Decompose()`, and `Dispose()` to this **alpha version** release.


This **alpha release version** allows the user to specify any location from which to load the **vm6502q/qrack** compiled libraries, by setting the environment variable `PYQRACK_SHARED_LIB_PATH`.


This fixes the Mac build, bumping **alpha release** v0.1.0 and v0.1.1.


This fixes the Windows build, to bump **alpha version** v0.1.0


This is the first **alpha** version release of **PyQrack**. It includes **vm6502q/qrack** shared libraries and static libraries. **For much more control over the package options, we suggest that advanced users build qrack and pyqrack from source,** but this package represents the most commonly demanded build configuration.