bocpy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bocpy-0.1.0/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) Microsoft Corporation.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bocpy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.4
2
+ Name: bocpy
3
+ Version: 0.1.0
4
+ Summary: boc is a Python extension that adds Behavior-oriented concurrency built on top of cross-interpreter data.
5
+ Author-email: Pyrona Team <pyrona@microsoft.com>
6
+ License-Expression: MIT
7
+ Project-URL: homepage, https://microsoft.github.io/bocpy/
8
+ Project-URL: source, https://github.com/microsoft/bocpy
9
+ Project-URL: documentation, https://microsoft.github.io/bocpy/docs
10
+ Project-URL: issues, https://github.com/microsoft/bocpy/issues
11
+ Keywords: behavior-oriented,concurrency,subinterpreters
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: Implementation :: CPython
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE.md
17
+ Provides-Extra: test
18
+ Requires-Dist: pytest-md; extra == "test"
19
+ Requires-Dist: pytest-emoji; extra == "test"
20
+ Requires-Dist: pytest-cov; extra == "test"
21
+ Requires-Dist: pytest; extra == "test"
22
+ Provides-Extra: linting
23
+ Requires-Dist: flake8; extra == "linting"
24
+ Requires-Dist: flake8-bugbear; extra == "linting"
25
+ Requires-Dist: flake8-builtins; extra == "linting"
26
+ Requires-Dist: flake8-docstrings; extra == "linting"
27
+ Requires-Dist: flake8-import-order; extra == "linting"
28
+ Requires-Dist: flake8-quotes; extra == "linting"
29
+ Requires-Dist: pep8-naming; extra == "linting"
30
+ Provides-Extra: docs
31
+ Requires-Dist: sphinx; extra == "docs"
32
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
33
+ Requires-Dist: enum-tools[sphinx]; extra == "docs"
34
+ Provides-Extra: boids
35
+ Requires-Dist: pyglet; extra == "boids"
36
+ Dynamic: license-file
37
+
38
+ # bocpy
39
+
40
+ ![BOC Logo](http://microsoft.github.io/bocpy/images/logo.svg)
41
+
42
+ Behavior-Oriented Concurrency (*BOC*) is a new paradigm for parallel and concurrent
43
+ programming which is particularly well-suited to Python. In a BOC program, data is
44
+ shared such that each behavior has unique temporal ownership of the data, removing
45
+ the need for locks to coordinate access. For Python programmers, this brings a lot
46
+ of benefits. Behaviors are implemented as decorated functions, and from the programmer's
47
+ perspective, those functions work like normal. Importantly, the programmer's task
48
+ shifts from solving concurrent data access problems to organizing data flow through
49
+ functions. The resulting programs are easier to understand, easier to support, easier
50
+ to extend, and unlock multi-core performance due to the ability to schedule behaviors
51
+ to run efficiently across multiple processes.
52
+
53
+ BOC has been implemented in several languages, including as a foundational aspect
54
+ of the research language Verona, and now has been implemented in Python.
55
+
56
+ ## Getting Started
57
+
58
+ You can install `boc` via PyPi:
59
+
60
+ pip install bocpy
61
+
62
+ We provide pre-compiled wheels for Python 3.10 onwards on most platforms, but if
63
+ you have problems with your particular platform/version combination, please file
64
+ an issue on [this repository](https://github.com/microsoft/bocpy/issues).
65
+
66
+ > [!NOTE]
67
+ > the `boc` library depends on the Cross-Interpreter Data mechanism, which was
68
+ > introduced in Python 3.7. We explicitly test and provide wheels for all versions
69
+ > of Python that have not been end-of-lifed (3.10.19 as of time of writing is the
70
+ > oldest version we support). The library may not work in older versions of Python.
71
+
72
+ A behavior can be thought of as a function which depends on zero or more
73
+ concurrently-owned data objects (which we call **cowns**). As a programmer, you
74
+ indicate that you want the function to be called once all of those resources are
75
+ available. For example, let's say that you had two complex and time-consuming
76
+ operations, and you needed to act on the basis of both of their outcomes:
77
+
78
+ ```python
79
+
80
+ def buy_cheese():
81
+ logger = logging.getLogger("cheese_shop")
82
+ for name in all_known_cheeses():
83
+ if is_available(logger, name):
84
+ return name
85
+
86
+ cleanup_shop(logger)
87
+ return None
88
+
89
+
90
+ def order_meal(exclude: str):
91
+ logger = logging.getLogger("greasy_spoon")
92
+ for dish in menu():
93
+ logger.info(dish)
94
+ if exclude.lower() not in dish.lower():
95
+ logger.info(f"That doesn't have much {exclude} in it")
96
+ return dish
97
+
98
+ vikings(logger)
99
+ if random.random() < 0.3:
100
+ logger.info("<bloody vikings>")
101
+
102
+ return None
103
+
104
+
105
+ cheese = buy_cheese()
106
+ meal = order_meal(exclude="spam")
107
+
108
+ if meal is not None:
109
+ eat(meal)
110
+ elif cheese is not None:
111
+ eat(cheese)
112
+
113
+ if meal is not None:
114
+ print("I really wanted some cheese...")
115
+ elif cheese is not None:
116
+ print("Cheesy comestibles")
117
+
118
+ return_to_library()
119
+ ```
120
+
121
+ The code above will work, but requires the purveying of cheese and the navigation
122
+ of the menu for non-spam options to happen sequentially. If we wanted to do these
123
+ tasks in parallel, we will end up with some version of nested waiting, which can
124
+ result in deadlock. With BOC, we would write the above like this:
125
+
126
+ ```python
127
+ from bocpy import wait, when, Cown
128
+
129
+ # ...
130
+
131
+ def buy_cheese():
132
+ cheese = Cown(None)
133
+
134
+ @when(cheese)
135
+ def _(cheese):
136
+ logger = logging.getLogger("cheese_shop")
137
+ for name in all_known_cheeses():
138
+ if is_available(logger, name):
139
+ cheese.value = name
140
+ return
141
+
142
+ cleanup_shop(logger)
143
+
144
+ return cheese
145
+
146
+
147
+ def order_meal(exclude: str):
148
+ order = Cown(None)
149
+
150
+ @when(order)
151
+ def _(order):
152
+ logger = logging.getLogger("greasy_spoon")
153
+ logger.info("We have...")
154
+ for dish in menu():
155
+ logger.info(dish)
156
+ if exclude.lower() not in dish.lower():
157
+ logger.info(f"That doesn't have much {exclude} in it")
158
+ order.value = dish
159
+ return
160
+
161
+ vikings(logger)
162
+ if random.random() < 0.3:
163
+ logger.info("<bloody vikings>")
164
+
165
+ return order
166
+
167
+
168
+ cheese = buy_cheese()
169
+ meal = order_meal(exclude="spam")
170
+
171
+
172
+ @when(cheese, meal)
173
+ def _(cheese, meal):
174
+ if meal.value is not None:
175
+ eat(meal.value)
176
+ elif cheese.value is not None:
177
+ eat(cheese.value)
178
+ else:
179
+ print("<stomach rumbles>")
180
+
181
+
182
+ @when(cheese, meal)
183
+ def _(cheese, meal):
184
+ if meal.value is not None:
185
+ print("I really wanted cheese...")
186
+ elif cheese.value is not None:
187
+ print("Cheesy comestibles!")
188
+
189
+ return_to_library()
190
+
191
+
192
+ wait()
193
+ ```
194
+
195
+ You can view the full example
196
+ [here](https://github.com/microsoft/bocpy/blob/main/examples/sketches.py)
197
+
198
+ The underlying BOC scheduler ensures that this operates without deadlock, by
199
+ construction.
200
+
201
+ ### Examples
202
+
203
+ We provide a few examples to show different ways of using BOC in a program:
204
+
205
+ 1. [Atomic Bank Transfer](https://github.com/microsoft/bocpy/blob/main/examples/bank.py): Shows an example
206
+ where two objects (in this case, bank accounts), interact in an atomic way.
207
+ 2. [Dining Philosophers](https://github.com/microsoft/bocpy/blob/main/examples/dining_philosophers.py):
208
+ The classic Dining Philosphers problem implemented using BOC.
209
+ 3. [Fibonacci](https://github.com/microsoft/bocpy/blob/main/examples/fibonacci.py): A
210
+ parallel implementation of Fibonacci calculation.
211
+ 4. [Cooking](https://github.com/microsoft/bocpy/blob/main/examples/cooking_boc.py): The example from
212
+ the [BOC tutorial](https://microsoft.github.io/bocpy/).
213
+ 5. [Boids](https://github.com/microsoft/bocpy/blob/main/examples/boids.py): An agent-based bird flocking
214
+ example demonstrating the `Matrix` class to do distributed computation over cores.
215
+
216
+
217
+ ## Why BOC for Python?
218
+ For many Python programmers, the GIL has established a programming model in which
219
+ they do not have to think about the many potential issues that are introduced by
220
+ concurrency, in particular data races. One of the best features of BOC is that, due
221
+ to the way behaviors interact with concurrently owned data (*cowns*), each behavior
222
+ can operate over its data without a need to change this familiar programming model.
223
+ Even in a free-threading context, BOC will reduce contention on locks and provide
224
+ programs which are data-race free by construction. Our initial research and experiments
225
+ with BOC have shown near linear scaling over cores, with up to 32 concurrent worker
226
+ processes.
227
+
228
+ ### This library
229
+ Our implementation is built on top of the subinterpreters mechanism and the
230
+ Cross-Interpreter Data, or `XIData`, API. As of Python 3.12, sub-interpreters have
231
+ their own GIL and thus run in parallel, and thus BOC will also run fully in
232
+ parallel.
233
+
234
+ In addition the providing the `when` function decorator, the library also exposes
235
+ low-level Erlang-style `send` and selective `receive` functions which enable
236
+ lock-free communication across threads and subinterpreters. See the
237
+ [Primes](https://github.com/microsoft/bocpy/blob/main/examples/primes.py) and
238
+ [Calculator](https://github.com/microsoft/bocpy/blob/main/examples/calculator.py)
239
+ examples for the usage of these lower-level functions.
240
+
241
+ ### Additional Info
242
+ BOC is built on a solid foundation of serious scholarship and engineering. For further reading, please see:
243
+ 1. [When Concurrency Matters: Behaviour-Oriented Concurrency](https://dl.acm.org/doi/10.1145/3622852)
244
+ 2. [Reference implementation in C#](https://github.com/microsoft/verona-rt/tree/main/docs/internal/concurrency/modelimpl)
245
+ 3. [OOPSLA23 Talk](https://www.youtube.com/watch?v=iX8TJWonbGU)
246
+
247
+ > **Trademarks** This project may contain trademarks or logos for projects, products, or services.
248
+ > Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s
249
+ > Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this
250
+ > project must not cause confusion or imply Microsoft sponsorship. Any use of third-party
251
+ > trademarks or logos are subject to those third-party’s policies.
bocpy-0.1.0/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # bocpy
2
+
3
+ ![BOC Logo](http://microsoft.github.io/bocpy/images/logo.svg)
4
+
5
+ Behavior-Oriented Concurrency (*BOC*) is a new paradigm for parallel and concurrent
6
+ programming which is particularly well-suited to Python. In a BOC program, data is
7
+ shared such that each behavior has unique temporal ownership of the data, removing
8
+ the need for locks to coordinate access. For Python programmers, this brings a lot
9
+ of benefits. Behaviors are implemented as decorated functions, and from the programmer's
10
+ perspective, those functions work like normal. Importantly, the programmer's task
11
+ shifts from solving concurrent data access problems to organizing data flow through
12
+ functions. The resulting programs are easier to understand, easier to support, easier
13
+ to extend, and unlock multi-core performance due to the ability to schedule behaviors
14
+ to run efficiently across multiple processes.
15
+
16
+ BOC has been implemented in several languages, including as a foundational aspect
17
+ of the research language Verona, and now has been implemented in Python.
18
+
19
+ ## Getting Started
20
+
21
+ You can install `boc` via PyPi:
22
+
23
+ pip install bocpy
24
+
25
+ We provide pre-compiled wheels for Python 3.10 onwards on most platforms, but if
26
+ you have problems with your particular platform/version combination, please file
27
+ an issue on [this repository](https://github.com/microsoft/bocpy/issues).
28
+
29
+ > [!NOTE]
30
+ > the `boc` library depends on the Cross-Interpreter Data mechanism, which was
31
+ > introduced in Python 3.7. We explicitly test and provide wheels for all versions
32
+ > of Python that have not been end-of-lifed (3.10.19 as of time of writing is the
33
+ > oldest version we support). The library may not work in older versions of Python.
34
+
35
+ A behavior can be thought of as a function which depends on zero or more
36
+ concurrently-owned data objects (which we call **cowns**). As a programmer, you
37
+ indicate that you want the function to be called once all of those resources are
38
+ available. For example, let's say that you had two complex and time-consuming
39
+ operations, and you needed to act on the basis of both of their outcomes:
40
+
41
+ ```python
42
+
43
+ def buy_cheese():
44
+ logger = logging.getLogger("cheese_shop")
45
+ for name in all_known_cheeses():
46
+ if is_available(logger, name):
47
+ return name
48
+
49
+ cleanup_shop(logger)
50
+ return None
51
+
52
+
53
+ def order_meal(exclude: str):
54
+ logger = logging.getLogger("greasy_spoon")
55
+ for dish in menu():
56
+ logger.info(dish)
57
+ if exclude.lower() not in dish.lower():
58
+ logger.info(f"That doesn't have much {exclude} in it")
59
+ return dish
60
+
61
+ vikings(logger)
62
+ if random.random() < 0.3:
63
+ logger.info("<bloody vikings>")
64
+
65
+ return None
66
+
67
+
68
+ cheese = buy_cheese()
69
+ meal = order_meal(exclude="spam")
70
+
71
+ if meal is not None:
72
+ eat(meal)
73
+ elif cheese is not None:
74
+ eat(cheese)
75
+
76
+ if meal is not None:
77
+ print("I really wanted some cheese...")
78
+ elif cheese is not None:
79
+ print("Cheesy comestibles")
80
+
81
+ return_to_library()
82
+ ```
83
+
84
+ The code above will work, but requires the purveying of cheese and the navigation
85
+ of the menu for non-spam options to happen sequentially. If we wanted to do these
86
+ tasks in parallel, we will end up with some version of nested waiting, which can
87
+ result in deadlock. With BOC, we would write the above like this:
88
+
89
+ ```python
90
+ from bocpy import wait, when, Cown
91
+
92
+ # ...
93
+
94
+ def buy_cheese():
95
+ cheese = Cown(None)
96
+
97
+ @when(cheese)
98
+ def _(cheese):
99
+ logger = logging.getLogger("cheese_shop")
100
+ for name in all_known_cheeses():
101
+ if is_available(logger, name):
102
+ cheese.value = name
103
+ return
104
+
105
+ cleanup_shop(logger)
106
+
107
+ return cheese
108
+
109
+
110
+ def order_meal(exclude: str):
111
+ order = Cown(None)
112
+
113
+ @when(order)
114
+ def _(order):
115
+ logger = logging.getLogger("greasy_spoon")
116
+ logger.info("We have...")
117
+ for dish in menu():
118
+ logger.info(dish)
119
+ if exclude.lower() not in dish.lower():
120
+ logger.info(f"That doesn't have much {exclude} in it")
121
+ order.value = dish
122
+ return
123
+
124
+ vikings(logger)
125
+ if random.random() < 0.3:
126
+ logger.info("<bloody vikings>")
127
+
128
+ return order
129
+
130
+
131
+ cheese = buy_cheese()
132
+ meal = order_meal(exclude="spam")
133
+
134
+
135
+ @when(cheese, meal)
136
+ def _(cheese, meal):
137
+ if meal.value is not None:
138
+ eat(meal.value)
139
+ elif cheese.value is not None:
140
+ eat(cheese.value)
141
+ else:
142
+ print("<stomach rumbles>")
143
+
144
+
145
+ @when(cheese, meal)
146
+ def _(cheese, meal):
147
+ if meal.value is not None:
148
+ print("I really wanted cheese...")
149
+ elif cheese.value is not None:
150
+ print("Cheesy comestibles!")
151
+
152
+ return_to_library()
153
+
154
+
155
+ wait()
156
+ ```
157
+
158
+ You can view the full example
159
+ [here](https://github.com/microsoft/bocpy/blob/main/examples/sketches.py)
160
+
161
+ The underlying BOC scheduler ensures that this operates without deadlock, by
162
+ construction.
163
+
164
+ ### Examples
165
+
166
+ We provide a few examples to show different ways of using BOC in a program:
167
+
168
+ 1. [Atomic Bank Transfer](https://github.com/microsoft/bocpy/blob/main/examples/bank.py): Shows an example
169
+ where two objects (in this case, bank accounts), interact in an atomic way.
170
+ 2. [Dining Philosophers](https://github.com/microsoft/bocpy/blob/main/examples/dining_philosophers.py):
171
+ The classic Dining Philosphers problem implemented using BOC.
172
+ 3. [Fibonacci](https://github.com/microsoft/bocpy/blob/main/examples/fibonacci.py): A
173
+ parallel implementation of Fibonacci calculation.
174
+ 4. [Cooking](https://github.com/microsoft/bocpy/blob/main/examples/cooking_boc.py): The example from
175
+ the [BOC tutorial](https://microsoft.github.io/bocpy/).
176
+ 5. [Boids](https://github.com/microsoft/bocpy/blob/main/examples/boids.py): An agent-based bird flocking
177
+ example demonstrating the `Matrix` class to do distributed computation over cores.
178
+
179
+
180
+ ## Why BOC for Python?
181
+ For many Python programmers, the GIL has established a programming model in which
182
+ they do not have to think about the many potential issues that are introduced by
183
+ concurrency, in particular data races. One of the best features of BOC is that, due
184
+ to the way behaviors interact with concurrently owned data (*cowns*), each behavior
185
+ can operate over its data without a need to change this familiar programming model.
186
+ Even in a free-threading context, BOC will reduce contention on locks and provide
187
+ programs which are data-race free by construction. Our initial research and experiments
188
+ with BOC have shown near linear scaling over cores, with up to 32 concurrent worker
189
+ processes.
190
+
191
+ ### This library
192
+ Our implementation is built on top of the subinterpreters mechanism and the
193
+ Cross-Interpreter Data, or `XIData`, API. As of Python 3.12, sub-interpreters have
194
+ their own GIL and thus run in parallel, and thus BOC will also run fully in
195
+ parallel.
196
+
197
+ In addition the providing the `when` function decorator, the library also exposes
198
+ low-level Erlang-style `send` and selective `receive` functions which enable
199
+ lock-free communication across threads and subinterpreters. See the
200
+ [Primes](https://github.com/microsoft/bocpy/blob/main/examples/primes.py) and
201
+ [Calculator](https://github.com/microsoft/bocpy/blob/main/examples/calculator.py)
202
+ examples for the usage of these lower-level functions.
203
+
204
+ ### Additional Info
205
+ BOC is built on a solid foundation of serious scholarship and engineering. For further reading, please see:
206
+ 1. [When Concurrency Matters: Behaviour-Oriented Concurrency](https://dl.acm.org/doi/10.1145/3622852)
207
+ 2. [Reference implementation in C#](https://github.com/microsoft/verona-rt/tree/main/docs/internal/concurrency/modelimpl)
208
+ 3. [OOPSLA23 Talk](https://www.youtube.com/watch?v=iX8TJWonbGU)
209
+
210
+ > **Trademarks** This project may contain trademarks or logos for projects, products, or services.
211
+ > Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s
212
+ > Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this
213
+ > project must not cause confusion or imply Microsoft sponsorship. Any use of third-party
214
+ > trademarks or logos are subject to those third-party’s policies.
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "bocpy"
7
+ version = "0.1.0"
8
+ authors = [
9
+ {name = "Pyrona Team", email="pyrona@microsoft.com"}
10
+ ]
11
+ description = "boc is a Python extension that adds Behavior-oriented concurrency built on top of cross-interpreter data."
12
+ readme = "README.md"
13
+ keywords = ["behavior-oriented", "concurrency", "subinterpreters"]
14
+ license = "MIT"
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: Implementation :: CPython",
19
+
20
+ ]
21
+
22
+ [project.urls]
23
+ homepage = "https://microsoft.github.io/bocpy/"
24
+ source = "https://github.com/microsoft/bocpy"
25
+ documentation = "https://microsoft.github.io/bocpy/docs"
26
+ issues = "https://github.com/microsoft/bocpy/issues"
27
+
28
+ [project.optional-dependencies]
29
+ test = ["pytest-md", "pytest-emoji", "pytest-cov", "pytest"]
30
+ linting = ["flake8", "flake8-bugbear", "flake8-builtins", "flake8-docstrings", "flake8-import-order", "flake8-quotes", "pep8-naming"]
31
+ docs = ["sphinx", "sphinx-autodoc-typehints", "enum-tools[sphinx]"]
32
+ boids = ["pyglet"]
bocpy-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
bocpy-0.1.0/setup.py ADDED
@@ -0,0 +1,15 @@
1
+ from setuptools import Extension, setup
2
+
3
+ setup(
4
+ ext_modules=[
5
+ Extension(
6
+ name="bocpy._core",
7
+ sources=["src/bocpy/_core.c"],
8
+ ),
9
+ Extension(
10
+ name="bocpy._math",
11
+ sources=["src/bocpy/_math.c"],
12
+ ),
13
+
14
+ ]
15
+ )
@@ -0,0 +1,8 @@
1
+ """Behavior-oriented Concurrency."""
2
+
3
+ from ._core import receive, send, set_tags, TIMEOUT
4
+ from ._math import Matrix
5
+ from .behaviors import Behaviors, Cown, start, wait, when, whencall, WORKER_COUNT
6
+
7
+ __all__ = ["Matrix", "send", "receive", "set_tags", "TIMEOUT", "start",
8
+ "wait", "when", "whencall", "Behaviors", "Cown", "WORKER_COUNT"]