Release the compiled module on close
close() now clears _module (initialized to None) inside the active context together with the function references; lifecycle test asserts it is retained on failed activation and cleared after close. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4645e48a2c
commit
7281d91fd6
2 files changed
+8
-3
No files matched your search
@@ -57,7 +57,7 @@ class PeriodicBlockStepper:
|
|||||||
self._status = "new"
|
self._status = "new"
|
||||||
self._step_count = 0
|
self._step_count = 0
|
||||||
self._allocations = []
|
self._allocations = []
|
||||||
self._stream = self._copy = self._step = None
|
self._stream = self._module = self._copy = self._step = None
|
||||||
with self.ctx.activate():
|
with self.ctx.activate():
|
||||||
try:
|
try:
|
||||||
free, _ = cuda.mem_get_info()
|
free, _ = cuda.mem_get_info()
|
||||||
@@ -179,7 +179,7 @@ class PeriodicBlockStepper:
|
|||||||
self._stream.synchronize()
|
self._stream.synchronize()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
error = exc
|
error = exc
|
||||||
self._copy = self._step = None
|
self._copy = self._step = self._module = None
|
||||||
for pointer in self._allocations:
|
for pointer in self._allocations:
|
||||||
try:
|
try:
|
||||||
pointer.free()
|
pointer.free()
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class CpuContracts(unittest.TestCase):
|
|||||||
backend._lock = RLock()
|
backend._lock = RLock()
|
||||||
backend._status = "ready"
|
backend._status = "ready"
|
||||||
backend._stream = Mock()
|
backend._stream = Mock()
|
||||||
|
backend._module = Mock()
|
||||||
backend._copy = backend._step = Mock()
|
backend._copy = backend._step = Mock()
|
||||||
backend._dst, backend._src = Mock(), Mock()
|
backend._dst, backend._src = Mock(), Mock()
|
||||||
backend._block, backend._grid, backend._copy_grid = (32, 1, 1), (1, 1, 1), (1, 1)
|
backend._block, backend._grid, backend._copy_grid = (32, 1, 1), (1, 1, 1), (1, 1)
|
||||||
@@ -155,7 +156,7 @@ class CpuContracts(unittest.TestCase):
|
|||||||
|
|
||||||
def test_activation_failure_retains_resources_for_retry(self):
|
def test_activation_failure_retains_resources_for_retry(self):
|
||||||
backend = self.fake_backend()
|
backend = self.fake_backend()
|
||||||
allocations, stream = backend._allocations[:], backend._stream
|
allocations, stream, module = backend._allocations[:], backend._stream, backend._module
|
||||||
unavailable = MagicMock()
|
unavailable = MagicMock()
|
||||||
unavailable.__enter__.side_effect = RuntimeError("activation failed")
|
unavailable.__enter__.side_effect = RuntimeError("activation failed")
|
||||||
backend.ctx.activate = Mock(side_effect=[unavailable, nullcontext()])
|
backend.ctx.activate = Mock(side_effect=[unavailable, nullcontext()])
|
||||||
@@ -164,8 +165,12 @@ class CpuContracts(unittest.TestCase):
|
|||||||
self.assertEqual(backend._status, "failed")
|
self.assertEqual(backend._status, "failed")
|
||||||
self.assertEqual(backend._allocations, allocations)
|
self.assertEqual(backend._allocations, allocations)
|
||||||
self.assertIs(backend._stream, stream)
|
self.assertIs(backend._stream, stream)
|
||||||
|
self.assertIs(backend._module, module)
|
||||||
backend.close()
|
backend.close()
|
||||||
self.assertEqual(backend._status, "closed")
|
self.assertEqual(backend._status, "closed")
|
||||||
|
self.assertIsNone(backend._module)
|
||||||
|
self.assertIsNone(backend._copy)
|
||||||
|
self.assertIsNone(backend._step)
|
||||||
for allocation in allocations:
|
for allocation in allocations:
|
||||||
allocation.free.assert_called_once()
|
allocation.free.assert_called_once()
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user