Repository: numba/numba

Issue:
CUDA deallocation bug
I get this kind of messages multiple times when running the CUDA test suite:

```
test_pinned (numba.cuda.tests.cudadrv.test_pinned.TestPinned) ... Exception ignored in: <finalize object at 0x7f75a9726260; dead>
Traceback (most recent call last):
  File "/home/antoine/numba/numba/utils.py", line 593, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "/home/antoine/numba/numba/cuda/cudadrv/driver.py", line 847, in core
    deallocs.add_item(driver.cuStreamDestroy, handle)
AttributeError: 'UniqueDict' object has no attribute 'add_item'
ok
test_unpinned (numba.cuda.tests.cudadrv.test_pinned.TestPinned) ... Exception ignored in: <finalize object at 0x7f75a97262a0; dead>
Traceback (most recent call last):
  File "/home/antoine/numba/numba/utils.py", line 593, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "/home/antoine/numba/numba/cuda/cudadrv/driver.py", line 847, in core
    deallocs.add_item(driver.cuStreamDestroy, handle)
AttributeError: 'UniqueDict' object has no attribute 'add_item'
ok
```



Discussion:

Resolving patch:
diff --git a/numba/cuda/cudadrv/driver.py b/numba/cuda/cudadrv/driver.py
--- a/numba/cuda/cudadrv/driver.py
+++ b/numba/cuda/cudadrv/driver.py
@@ -744,7 +744,7 @@ def create_stream(self):
         handle = drvapi.cu_stream()
         driver.cuStreamCreate(byref(handle), 0)
         return Stream(weakref.proxy(self), handle,
-                      _stream_finalizer(self.allocations, handle))
+                      _stream_finalizer(self.deallocations, handle))
 
     def create_event(self, timing=True):
         handle = drvapi.cu_event()


Test patch:
diff --git a/numba/cuda/tests/cudadrv/test_deallocations.py b/numba/cuda/tests/cudadrv/test_deallocations.py
--- a/numba/cuda/tests/cudadrv/test_deallocations.py
+++ b/numba/cuda/tests/cudadrv/test_deallocations.py
@@ -1,9 +1,12 @@
 from __future__ import division
 
+from contextlib import contextmanager
+
 import numpy as np
 
 from numba import cuda, config
 from numba.cuda.testing import unittest, skip_on_cudasim
+from numba.tests.support import captured_stderr
 
 
 @skip_on_cudasim('not supported on CUDASIM')
@@ -127,5 +130,48 @@ def test_context_manager(self):
             pass
 
 
+@skip_on_cudasim('not supported on CUDASIM')
+class TestDel(unittest.TestCase):
+    """
+    Ensure resources are deleted properly without ignored exception.
+    """
+    @contextmanager
+    def check_ignored_exception(self, ctx):
+        with captured_stderr() as cap:
+            yield
+            ctx.deallocations.clear()
+        self.assertFalse(cap.getvalue())
+
+    def test_stream(self):
+        ctx = cuda.current_context()
+        stream = ctx.create_stream()
+        with self.check_ignored_exception(ctx):
+            del stream
+
+    def test_event(self):
+        ctx = cuda.current_context()
+        event = ctx.create_event()
+        with self.check_ignored_exception(ctx):
+            del event
+
+    def test_pinned_memory(self):
+        ctx = cuda.current_context()
+        mem = ctx.memhostalloc(32)
+        with self.check_ignored_exception(ctx):
+            del mem
+
+    def test_mapped_memory(self):
+        ctx = cuda.current_context()
+        mem = ctx.memhostalloc(32, mapped=True)
+        with self.check_ignored_exception(ctx):
+            del mem
+
+    def test_device_memory(self):
+        ctx = cuda.current_context()
+        mem = ctx.memalloc(32)
+        with self.check_ignored_exception(ctx):
+            del mem
+
+
 if __name__ == '__main__':
     unittest.main()
\ No newline at end of file