You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by zh...@apache.org on 2020/07/12 03:45:14 UTC

[incubator-mxnet] branch v1.7.x updated: Revert "Fix memory leaks in Gluon (#18328) (#18358)" (#18692)

This is an automated email from the ASF dual-hosted git repository.

zhasheng pushed a commit to branch v1.7.x
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/v1.7.x by this push:
     new c4c7b11  Revert "Fix memory leaks in Gluon (#18328) (#18358)" (#18692)
c4c7b11 is described below

commit c4c7b11a84fd8f0333131b6b228afb4832fc49de
Author: Ziyi Mu <zi...@columbia.edu>
AuthorDate: Sat Jul 11 20:44:16 2020 -0700

    Revert "Fix memory leaks in Gluon (#18328) (#18358)" (#18692)
    
    This reverts commit c4d9270dde5c091386dbdbd53f8060a73b98cbc9.
---
 python/mxnet/gluon/block.py                | 21 ++++++----------
 tests/python/unittest/test_gluon.py        | 39 ------------------------------
 tests/python/unittest/test_thread_local.py |  5 ++--
 3 files changed, 10 insertions(+), 55 deletions(-)

diff --git a/python/mxnet/gluon/block.py b/python/mxnet/gluon/block.py
index 968c787..bed6679 100644
--- a/python/mxnet/gluon/block.py
+++ b/python/mxnet/gluon/block.py
@@ -23,10 +23,8 @@ __all__ = ['Block', 'HybridBlock', 'SymbolBlock']
 import threading
 import copy
 import warnings
-import weakref
-from collections import OrderedDict, defaultdict
-
 import re
+from collections import OrderedDict, defaultdict
 import numpy as np
 
 from ..base import mx_real_t, MXNetError
@@ -48,7 +46,7 @@ class _BlockScope(object):
     _current = threading.local()
 
     def __init__(self, block):
-        self._block = weakref.ref(block) if block is not None else None
+        self._block = block
         self._counter = {}
         self._old_scope = None
         self._name_scope = None
@@ -57,8 +55,7 @@ class _BlockScope(object):
     def create(prefix, params, hint):
         """Creates prefix and params for new `Block`."""
         current = getattr(_BlockScope._current, "value", None)
-        block = current._block() if current is not None else None
-        if current is None or block is None:
+        if current is None:
             if prefix is None:
                 if not hasattr(_name.NameManager._current, "value"):
                     _name.NameManager._current.value = _name.NameManager()
@@ -74,25 +71,23 @@ class _BlockScope(object):
             prefix = '%s%d_'%(hint, count)
             current._counter[hint] = count + 1
         if params is None:
-            parent = block.params
+            parent = current._block.params
             params = ParameterDict(parent.prefix+prefix, parent._shared)
         else:
             params = ParameterDict(params.prefix, params)
-        return block.prefix + prefix, params
+        return current._block.prefix+prefix, params
 
     def __enter__(self):
-        block = self._block()
-        if block is None or block._empty_prefix:
+        if self._block._empty_prefix:
             return self
         self._old_scope = getattr(_BlockScope._current, "value", None)
         _BlockScope._current.value = self
-        self._name_scope = _name.Prefix(block.prefix)
+        self._name_scope = _name.Prefix(self._block.prefix)
         self._name_scope.__enter__()
         return self
 
     def __exit__(self, ptype, value, trace):
-        block = self._block()
-        if block is None or block._empty_prefix:
+        if self._block._empty_prefix:
             return
         self._name_scope.__exit__(ptype, value, trace)
         self._name_scope = None
diff --git a/tests/python/unittest/test_gluon.py b/tests/python/unittest/test_gluon.py
index cf6bc36..a026825 100644
--- a/tests/python/unittest/test_gluon.py
+++ b/tests/python/unittest/test_gluon.py
@@ -17,7 +17,6 @@
 
 import os
 import tempfile
-import gc
 
 import mxnet as mx
 from mxnet import gluon
@@ -3213,44 +3212,6 @@ def test_reqs_switching_training_inference():
 
     mx.test_utils.assert_almost_equal(grad1, grad2)
 
-def test_no_memory_leak_in_gluon():
-    # Collect all other garbage prior to this test. Otherwise the test may fail
-    # due to unrelated memory leaks.
-    gc.collect()
-
-    gc_flags = gc.get_debug()
-    gc.set_debug(gc.DEBUG_SAVEALL)
-    net = mx.gluon.nn.Dense(10, in_units=10)
-    net.initialize()
-    del net
-    gc.collect()
-    gc.set_debug(gc_flags)  # reset gc flags
-
-    # Check for leaked NDArrays
-    seen = set()
-    def has_array(element):
-        try:
-            if element in seen:
-                return False
-            seen.add(element)
-        except TypeError:  # unhashable
-            pass
-
-        if isinstance(element, mx.nd._internal.NDArrayBase):
-            return True
-        elif hasattr(element, '__dict__'):
-            return any(has_array(x) for x in vars(element))
-        elif isinstance(element, dict):
-            return any(has_array(x) for x in element.items())
-        else:
-            try:
-                return any(has_array(x) for x in element)
-            except (TypeError, KeyError):
-                return False
-
-    assert not any(has_array(x) for x in gc.garbage), 'Found leaked NDArrays due to reference cycles'
-    del gc.garbage[:]
-
 if __name__ == '__main__':
     import nose
     nose.runmodule()
diff --git a/tests/python/unittest/test_thread_local.py b/tests/python/unittest/test_thread_local.py
index 50ecb06..f0e3c66 100644
--- a/tests/python/unittest/test_thread_local.py
+++ b/tests/python/unittest/test_thread_local.py
@@ -124,9 +124,8 @@ def test_blockscope():
     status = [False]
     event = threading.Event()
     def f():
-        net = dummy_block("spawned_")  # BlockScope only keeps a weakref to the Block
-        with block._BlockScope(net):
-            x = NameManager.current.get(None, "hello")
+        with block._BlockScope(dummy_block("spawned_")):
+            x= NameManager.current.get(None, "hello")
             event.wait()
             if x == "spawned_hello0":
                 status[0] = True