# PyZas!: A Python library for atomic integer operations
**PyZas** is a Python library designed for performing atomic integer operations with the speed and efficiency of a zas!
(Inspired by the sudden impact sound 'zas', a Spanish onomatopoeia). PyZas ensures your calculations are executed atomically and safely. Perfect
for scenarios requiring quick, thread-safe manipulations.
## Installation
You can install PyZas via pip:
```bash
pip install pyzas
```
## Usage
The PyZas module implements the following atomic types:
* **AtomicInt**: An atomic int type
* **AtomicLong**: An atomic 64-bytes int type
* **AtomicULong**: An atomic 64-bytes unsigned int type
The three types implement the following functions:
* **free_lock_level() -> int**: Determines if the atomic object is implemented lock-free
* **load() -> int**: Reads a value from an atomic object
* **store(int)**: Stores a value in an atomic object
* **exchange(int) -> int**: Atomically replaces the value in an atomic object
* **fetch_add(int) -> int**: Performs atomic addition
* **fetch_sub(int) -> int**: Performs atomic subtraction
* **compare_exchange(int, int) -> int**: Swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value
Module also implements **AtomicFlag** with support for spinlock:
* **test_and_set() -> bool**: sets an atomic flag to true and returns the old value
* **clear()**: Sets the atomic_flag to false
* **spin_lock()**: Causes a thread trying to acquire a lock to simply wait in a loop ("spin")
* **spin_unlock()**: Releases the lock
For more details:
```python
help(pyzas)
```
## Example
```python
import pyzas
n = pyzas.AtomicInt(0)
n.fetch_add(1)
print(n.load())
```
## Performance Test
```python
from multiprocessing.pool import ThreadPool
import threading
import time
import sys
import pyzas.pyzas as pyzas
def main(threads, its):
e = 0
atomic_e = pyzas.AtomicInt()
lock = threading.Lock()
def test_lock(i):
nonlocal e
with lock:
e = e + 1
def test_atomic(i):
atomic_e.fetch_add(1)
start = time.time()
with ThreadPool(threads) as p:
list(p.map(test_lock, range(its)))
print("Testing with lock", e, time.time() - start)
start = time.time()
with ThreadPool(threads) as p:
list(p.map(test_atomic, range(its)))
print("Testing atomic ", atomic_e.load(), time.time() - start)
if __name__ == '__main__':
if len(sys.argv) < 3:
print(f"Use: python3 {sys.argv[0]} [threads] [its]", file=sys.stderr)
exit(-1)
main(int(sys.argv[1]), int(sys.argv[2]))
```
## Build from sources
Library is built using Poetry:
```bash
poetry build
```
Or to install the library with pip:
```bash
pip install .
```
*PYZAS_CFLAGS* environment variable can be used to add compilation options.
```bash
export PYZAS_CFLAGS="-O2"
poetry build
```
### Most common errors
#### - Visual Studio still has experimental support for atomics, so we need to enable it to compile the code.
```bash
SET PYZAS_CFLAGS=/std:c11 /experimental:c11atomics
poetry build # or pip install .
```
#### - cp313 version (with GIL) is being compiled instead of the cp313t version (free-threaded)
If your version has been compiled with GIL, even if you have the free-threaded binaries, it's possible that the build
is done for the GIL version. The build tools are still experimental, and don't have a way to fix the compile option,
so we have to do it manually.
```bash
export PYZAS_FIX_GIL=1 # Linux or MacOS
SET PYZAS_FIX_GIL=1 # Windows
```
If you want to install using the wheel, you'll need to add **t** after the version number. For example,
*pyzas-1.0-cp313-cp313-win_amd64.whl* should be *pyzas-1.0-cp313-cp313t-win_amd64.whl*.
Raw data
{
"_id": null,
"home_page": "https://github.com/citiususc/pyzas",
"name": "pyzas",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.13",
"maintainer_email": null,
"keywords": "HPC, OMP, OpenMP, Multi-language, Programming models",
"author": "Cesar Pomar",
"author_email": "cesaralfredo.pineiro@usc.es",
"download_url": "https://files.pythonhosted.org/packages/b3/c3/ccf0f2adc3003f7962841b250afd65bf2f087aabeebfc8bd100646714f09/pyzas-1.0.1.tar.gz",
"platform": null,
"description": "# PyZas!: A Python library for atomic integer operations\n\n**PyZas** is a Python library designed for performing atomic integer operations with the speed and efficiency of a zas!\n(Inspired by the sudden impact sound 'zas', a Spanish onomatopoeia). PyZas ensures your calculations are executed atomically and safely. Perfect \nfor scenarios requiring quick, thread-safe manipulations.\n\n## Installation\n\nYou can install PyZas via pip:\n\n```bash\npip install pyzas\n```\n\n## Usage\n\nThe PyZas module implements the following atomic types:\n\n* **AtomicInt**: An atomic int type\n* **AtomicLong**: An atomic 64-bytes int type\n* **AtomicULong**: An atomic 64-bytes unsigned int type\n\nThe three types implement the following functions:\n\n* **free_lock_level() -> int**: Determines if the atomic object is implemented lock-free\n* **load() -> int**: Reads a value from an atomic object\n* **store(int)**: Stores a value in an atomic object\n* **exchange(int) -> int**: Atomically replaces the value in an atomic object\n* **fetch_add(int) -> int**: Performs atomic addition\n* **fetch_sub(int) -> int**: Performs atomic subtraction\n* **compare_exchange(int, int) -> int**: Swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value\n\nModule also implements **AtomicFlag** with support for spinlock:\n\n* **test_and_set() -> bool**: sets an atomic flag to true and returns the old value\n* **clear()**: Sets the atomic_flag to false\n* **spin_lock()**: Causes a thread trying to acquire a lock to simply wait in a loop (\"spin\")\n* **spin_unlock()**: Releases the lock\n\nFor more details:\n\n```python\nhelp(pyzas)\n```\n\n## Example\n\n```python\nimport pyzas\n\nn = pyzas.AtomicInt(0)\nn.fetch_add(1)\nprint(n.load())\n```\n\n## Performance Test\n\n```python\nfrom multiprocessing.pool import ThreadPool\nimport threading\nimport time\nimport sys\n\nimport pyzas.pyzas as pyzas\n\n\ndef main(threads, its):\n e = 0\n atomic_e = pyzas.AtomicInt()\n lock = threading.Lock()\n\n def test_lock(i):\n nonlocal e\n with lock:\n e = e + 1\n\n def test_atomic(i):\n atomic_e.fetch_add(1)\n\n start = time.time()\n with ThreadPool(threads) as p:\n list(p.map(test_lock, range(its)))\n print(\"Testing with lock\", e, time.time() - start)\n\n start = time.time()\n with ThreadPool(threads) as p:\n list(p.map(test_atomic, range(its)))\n print(\"Testing atomic \", atomic_e.load(), time.time() - start)\n\n\nif __name__ == '__main__':\n if len(sys.argv) < 3:\n print(f\"Use: python3 {sys.argv[0]} [threads] [its]\", file=sys.stderr)\n exit(-1)\n main(int(sys.argv[1]), int(sys.argv[2]))\n```\n\n## Build from sources\n\nLibrary is built using Poetry:\n\n```bash\npoetry build\n```\n\nOr to install the library with pip:\n\n```bash\npip install .\n```\n\n*PYZAS_CFLAGS* environment variable can be used to add compilation options. \n\n```bash\nexport PYZAS_CFLAGS=\"-O2\"\npoetry build\n```\n\n### Most common errors\n\n#### - Visual Studio still has experimental support for atomics, so we need to enable it to compile the code.\n\n```bash\nSET PYZAS_CFLAGS=/std:c11 /experimental:c11atomics\npoetry build # or pip install .\n```\n\n#### - cp313 version (with GIL) is being compiled instead of the cp313t version (free-threaded)\n\nIf your version has been compiled with GIL, even if you have the free-threaded binaries, it's possible that the build \nis done for the GIL version. The build tools are still experimental, and don't have a way to fix the compile option, \nso we have to do it manually.\n\n```bash\nexport PYZAS_FIX_GIL=1 # Linux or MacOS\nSET PYZAS_FIX_GIL=1 # Windows\n```\n\nIf you want to install using the wheel, you'll need to add **t** after the version number. For example, \n*pyzas-1.0-cp313-cp313-win_amd64.whl* should be *pyzas-1.0-cp313-cp313t-win_amd64.whl*.\n\n",
"bugtrack_url": null,
"license": "LGPL-3.0-only",
"summary": "PyZas!: A Python library for atomic integer operations",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/citiususc/pyzas",
"Repository": "https://github.com/citiususc/pyzas"
},
"split_keywords": [
"hpc",
" omp",
" openmp",
" multi-language",
" programming models"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "80cf60efaa772c293129306b311d392445269195422cbd1398a79a8e1147b642",
"md5": "c102b612796f567a30abce65661e40c9",
"sha256": "f836b9b70a3d197aa5f3fb9b9f9c8f80bb266a08bab87aab4e04fbe8f44b6e44"
},
"downloads": -1,
"filename": "pyzas-1.0.1-cp313-cp313t-macosx_13_0_x86_64.whl",
"has_sig": false,
"md5_digest": "c102b612796f567a30abce65661e40c9",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": "<4.0,>=3.13",
"size": 20185,
"upload_time": "2024-06-11T14:16:52",
"upload_time_iso_8601": "2024-06-11T14:16:52.624412Z",
"url": "https://files.pythonhosted.org/packages/80/cf/60efaa772c293129306b311d392445269195422cbd1398a79a8e1147b642/pyzas-1.0.1-cp313-cp313t-macosx_13_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f9c787433383aca619652c6770fefad906ba879e8bd43351294c652da6cf3b2c",
"md5": "939692ecb4cc13999e955953bb432956",
"sha256": "a5e125052c534d72904bc837cfda9dc1d1f06bc4e782e62d21ea3d079e39dbae"
},
"downloads": -1,
"filename": "pyzas-1.0.1-cp313-cp313t-manylinux_2_31_aarch64.whl",
"has_sig": false,
"md5_digest": "939692ecb4cc13999e955953bb432956",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": "<4.0,>=3.13",
"size": 40888,
"upload_time": "2024-06-11T14:16:54",
"upload_time_iso_8601": "2024-06-11T14:16:54.530883Z",
"url": "https://files.pythonhosted.org/packages/f9/c7/87433383aca619652c6770fefad906ba879e8bd43351294c652da6cf3b2c/pyzas-1.0.1-cp313-cp313t-manylinux_2_31_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3743f50df0c85aa8a371e8256818d933ef23a7dd4be3ecaec74a863188b5b7b1",
"md5": "46cd911d74810a0cf0aec12d31092419",
"sha256": "e14b4b0ba14d567c3579d82c6ad18db156f4d571a202a53c120cde04d7fac258"
},
"downloads": -1,
"filename": "pyzas-1.0.1-cp313-cp313t-manylinux_2_31_x86_64.whl",
"has_sig": false,
"md5_digest": "46cd911d74810a0cf0aec12d31092419",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": "<4.0,>=3.13",
"size": 40690,
"upload_time": "2024-06-11T14:16:56",
"upload_time_iso_8601": "2024-06-11T14:16:56.269083Z",
"url": "https://files.pythonhosted.org/packages/37/43/f50df0c85aa8a371e8256818d933ef23a7dd4be3ecaec74a863188b5b7b1/pyzas-1.0.1-cp313-cp313t-manylinux_2_31_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a64b30f557832ec8aac7eecef8aa3b91f60ad99f6883a54d9b2bcb1d656158f8",
"md5": "1275fb070dadbfee4ba7f91022c9cf4c",
"sha256": "b1e63868735e4752107f73843c602acb7d7996cc02626eb3e9717bd106990b1e"
},
"downloads": -1,
"filename": "pyzas-1.0.1-cp313-cp313t-win_amd64.whl",
"has_sig": false,
"md5_digest": "1275fb070dadbfee4ba7f91022c9cf4c",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": "<4.0,>=3.13",
"size": 22462,
"upload_time": "2024-06-11T14:16:57",
"upload_time_iso_8601": "2024-06-11T14:16:57.804921Z",
"url": "https://files.pythonhosted.org/packages/a6/4b/30f557832ec8aac7eecef8aa3b91f60ad99f6883a54d9b2bcb1d656158f8/pyzas-1.0.1-cp313-cp313t-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b3c3ccf0f2adc3003f7962841b250afd65bf2f087aabeebfc8bd100646714f09",
"md5": "6c092ffbed9055ad50502590fdd3a7b5",
"sha256": "9d500dd1e7007489bcfe3d90c13da25b15f85cab79b699d137d91f6a88a10697"
},
"downloads": -1,
"filename": "pyzas-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "6c092ffbed9055ad50502590fdd3a7b5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.13",
"size": 15139,
"upload_time": "2024-06-11T14:16:59",
"upload_time_iso_8601": "2024-06-11T14:16:59.466808Z",
"url": "https://files.pythonhosted.org/packages/b3/c3/ccf0f2adc3003f7962841b250afd65bf2f087aabeebfc8bd100646714f09/pyzas-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-11 14:16:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "citiususc",
"github_project": "pyzas",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pyzas"
}