You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by an...@apache.org on 2018/06/22 22:59:12 UTC

[incubator-mxnet] branch master updated: [MXNET-558] Fix 'AttributeError: '_thread._local' object has no attribute 'value'' on distributed processing applications (#11332)

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

anirudh2290 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new 579e376  [MXNET-558] Fix 'AttributeError: '_thread._local' object has no attribute 'value'' on distributed processing applications (#11332)
579e376 is described below

commit 579e376edd461484a10bb93444e07e29df762208
Author: Thomas Delteil <th...@gmail.com>
AuthorDate: Fri Jun 22 15:59:03 2018 -0700

    [MXNET-558] Fix 'AttributeError: '_thread._local' object has no attribute 'value'' on distributed processing applications (#11332)
    
    * add scope to NameManager
    
    * add AttrScope scope
    
    * adding test
    
    * update NameManager
    
    * Trigger build
    
    * Trigger build
    
    * Add attribute checks for register module
---
 python/mxnet/gluon/block.py                |  2 ++
 python/mxnet/symbol/register.py            |  8 ++++++++
 python/mxnet/symbol/symbol.py              |  2 ++
 tests/python/unittest/test_thread_local.py | 29 +++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/python/mxnet/gluon/block.py b/python/mxnet/gluon/block.py
index 3dd7e94..0ef2849 100644
--- a/python/mxnet/gluon/block.py
+++ b/python/mxnet/gluon/block.py
@@ -50,6 +50,8 @@ class _BlockScope(object):
         current = getattr(_BlockScope._current, "value", None)
         if current is None:
             if prefix is None:
+                if not hasattr(_name.NameManager._current, "value"):
+                    _name.NameManager._current.value = _name.NameManager()
                 prefix = _name.NameManager._current.value.get(None, hint) + '_'
             if params is None:
                 params = ParameterDict(prefix)
diff --git a/python/mxnet/symbol/register.py b/python/mxnet/symbol/register.py
index 3e81dcf..c147914 100644
--- a/python/mxnet/symbol/register.py
+++ b/python/mxnet/symbol/register.py
@@ -113,8 +113,12 @@ def %s(*%s, **kwargs):"""%(func_name, arr_name))
             dtype_name, dtype_name, dtype_name))
             code.append("""
     attr = kwargs.pop('attr', None)
+    if not hasattr(AttrScope._current, "value"):
+        AttrScope._current.value = AttrScope()
     kwargs.update(AttrScope._current.value.get(attr))
     name = kwargs.pop('name', None)
+    if not hasattr(NameManager._current, "value"):
+        NameManager._current.value = NameManager()
     name = NameManager._current.value.get(name, '%s')
     _ = kwargs.pop('out', None)
     keys = []
@@ -141,6 +145,8 @@ def %s(*%s, **kwargs):"""%(func_name, arr_name))
 def %s(%s):"""%(func_name, ', '.join(signature)))
         if not signature_only:
             code.append("""
+    if not hasattr(AttrScope._current, "value"):
+        AttrScope._current.value = AttrScope()
     kwargs.update(AttrScope._current.value.get(attr))
     sym_kwargs = dict()
     _keys = []
@@ -172,6 +178,8 @@ def %s(%s):"""%(func_name, ', '.join(signature)))
         _vals.append(np.dtype(%s).name)"""%(dtype_name, dtype_name, dtype_name))
 
             code.append("""
+    if not hasattr(NameManager._current, "value"):
+        NameManager._current.value = NameManager()
     name = NameManager._current.value.get(name, '%s')
     return _symbol_creator(%d, None, sym_kwargs, _keys, _vals, name)"""%(
         func_name.lower(), handle.value))
diff --git a/python/mxnet/symbol/symbol.py b/python/mxnet/symbol/symbol.py
index fc1a71c..7e5b527 100644
--- a/python/mxnet/symbol/symbol.py
+++ b/python/mxnet/symbol/symbol.py
@@ -2451,6 +2451,8 @@ def var(name, attr=None, shape=None, lr_mult=None, wd_mult=None, dtype=None,
     handle = SymbolHandle()
     check_call(_LIB.MXSymbolCreateVariable(c_str(name), ctypes.byref(handle)))
     ret = Symbol(handle)
+    if not hasattr(AttrScope._current, "value"):
+        AttrScope._current.value = AttrScope()
     attr = AttrScope._current.value.get(attr)
     attr = {} if attr is None else attr
     if shape is not None:
diff --git a/tests/python/unittest/test_thread_local.py b/tests/python/unittest/test_thread_local.py
index a571a25..b553299 100644
--- a/tests/python/unittest/test_thread_local.py
+++ b/tests/python/unittest/test_thread_local.py
@@ -134,6 +134,35 @@ def test_blockscope():
     event.clear()
     assert status[0], "Spawned thread isn't using the correct blockscope namemanager"
 
+def test_createblock():
+    status = [False]
+    def f():
+        net = mx.gluon.nn.Dense(2)
+        net.initialize()
+        x = net(mx.nd.array([1, 2, 3]))
+        x.wait_to_read()
+        status[0] = True
+
+    thread = threading.Thread(target=f)
+    thread.start()
+    thread.join()
+    assert status[0], "Failed to create a layer within a thread"
+
+def test_symbol():
+    status = [False]
+    def f():
+        a = mx.sym.var("a")
+        b = mx.sym.var("b")
+        a_ = mx.nd.ones((2, 2))
+        c_ = a_.copy()
+        func1 = (a + b).bind(mx.cpu(), args={'a': a_, 'b': c_})
+        func1.forward()[0].wait_to_read()
+        status[0] = True
+    thread = threading.Thread(target=f)
+    thread.start()
+    thread.join()
+    assert status[0], "Failed to execute a symbolic graph within a thread"
+
 if __name__ == '__main__':
     import nose
     nose.runmodule()