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.