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