Skip to content

Commit 7a4345e

Browse files
committed
Clean up the requested vs allocated size mess
This commit adds a new `rsize` field+accessor for the requested size, and uses it where appropriate, to avoid headaches with the true allocated size not matching the requested one.
1 parent 7ec37f4 commit 7a4345e

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

src/appose/types.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,24 @@ class which can be used with a `with` statement. When the program flow
4545
`unlink_on_dispose` flag.
4646
"""
4747

48-
def __init__(self, name: str = None, create: bool = False, size: int = 0):
49-
super().__init__(name=name, create=create, size=size)
48+
def __init__(self, name: str = None, create: bool = False, rsize: int = 0):
49+
"""
50+
Create a new shared memory block, or attach to an existing one.
51+
52+
:param name:
53+
The unique name for the requested shared memory, specified as a
54+
string. If create is True (i.e. a new shared memory block) and
55+
no name is given, a novel name will be generated.
56+
:param create:
57+
Whether a new shared memory block is created (True)
58+
or an existing one is attached to (False).
59+
:param rsize:
60+
Requested size in bytes. The true allocated size will be at least
61+
this much, but may be rounded up to the next block size multiple,
62+
depending on the running platform.
63+
"""
64+
super().__init__(name=name, create=create, size=rsize)
65+
self.rsize = rsize
5066
self._unlink_on_dispose = create
5167
if _is_worker:
5268
# HACK: Remove this shared memory block from the resource_tracker,
@@ -146,7 +162,7 @@ def __init__(self, dtype: str, shape: Sequence[int], shm: SharedMemory = None):
146162
self.shape = shape
147163
self.shm = (
148164
SharedMemory(
149-
create=True, size=ceil(prod(shape) * _bytes_per_element(dtype))
165+
create=True, rsize=ceil(prod(shape) * _bytes_per_element(dtype))
150166
)
151167
if shm is None
152168
else shm
@@ -157,7 +173,7 @@ def __str__(self):
157173
f"NDArray("
158174
f"dtype='{self.dtype}', "
159175
f"shape={self.shape}, "
160-
f"shm='{self.shm.name}' ({self.shm.size}))"
176+
f"shm='{self.shm.name}' ({self.shm.rsize}))"
161177
)
162178

163179
def ndarray(self):
@@ -188,7 +204,7 @@ def default(self, obj):
188204
return {
189205
"appose_type": "shm",
190206
"name": obj.name,
191-
"size": obj.size,
207+
"rsize": obj.rsize,
192208
}
193209
if isinstance(obj, NDArray):
194210
return {
@@ -204,7 +220,7 @@ def _appose_object_hook(obj: Dict):
204220
atype = obj.get("appose_type")
205221
if atype == "shm":
206222
# Attach to existing shared memory block.
207-
return SharedMemory(name=(obj["name"]), size=(obj["size"]))
223+
return SharedMemory(name=(obj["name"]), rsize=(obj["rsize"]))
208224
elif atype == "ndarray":
209225
return NDArray(obj["dtype"], obj["shape"], obj["shm"])
210226
else:

tests/test_shm.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from appose.service import TaskStatus
3232

3333
ndarray_inspect = """
34+
task.outputs["rsize"] = data.shm.rsize
3435
task.outputs["size"] = data.shm.size
3536
task.outputs["dtype"] = data.dtype
3637
task.outputs["shape"] = data.shape
@@ -41,7 +42,7 @@
4142
def test_ndarray():
4243
env = appose.system()
4344
with env.python() as service:
44-
with appose.SharedMemory(create=True, size=2 * 2 * 20 * 25) as shm:
45+
with appose.SharedMemory(create=True, rsize=2 * 2 * 20 * 25) as shm:
4546
# Construct the data.
4647
shm.buf[0] = 123
4748
shm.buf[456] = 78
@@ -54,7 +55,10 @@ def test_ndarray():
5455

5556
# Validate the execution result.
5657
assert TaskStatus.COMPLETE == task.status
57-
assert 2 * 20 * 25 * 2 == task.outputs["size"]
58+
# The requested size is 2*20*25*2=2000, but actual allocated
59+
# shm size varies by platform; e.g. on macOS it is 16384.
60+
assert 2 * 20 * 25 * 2 == task.outputs["rsize"]
61+
assert task.outputs["size"] >= task.outputs["rsize"]
5862
assert "uint16" == task.outputs["dtype"]
5963
assert [2, 20, 25] == task.outputs["shape"]
6064
assert 123 + 78 + 210 == task.outputs["sum"]

tests/test_types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class TypesTest(unittest.TestCase):
5656
'"shm":{' # noqa: E131
5757
'"appose_type":"shm",' # noqa: E131
5858
'"name":"SHM_NAME",' # noqa: E131
59-
'"size":4000' # noqa: E131
59+
'"rsize":4000' # noqa: E131
6060
"}" # noqa: E131
6161
"}"
6262
# fmt: on
@@ -103,7 +103,7 @@ def test_encode(self):
103103
self.assertEqual(expected, json_str)
104104

105105
def test_decode(self):
106-
with appose.SharedMemory(create=True, size=4000) as shm:
106+
with appose.SharedMemory(create=True, rsize=4000) as shm:
107107
shm_name = shm.name
108108
data = appose.types.decode(self.JSON.replace("SHM_NAME", shm_name))
109109
self.assertIsNotNone(data)

0 commit comments

Comments
 (0)