google / tangent

Source-to-Source Debuggable Derivatives in Pure Python
Apache License 2.0
2.31k stars 434 forks source link

Failed to resolve name "x" used by "test" #57

Open stefdoerr opened 6 years ago

stefdoerr commented 6 years ago
def test():
    x = []
    for i in range(5):
        x.append(i)
    return x
In [10]: xxx = tangent.grad(test)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-10-e1ef2738f728> in <module>()
----> 1 xxx = tangent.grad(test)

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in grad(func, wrt, optimized, preserve_result, check_dims, verbose)
    384       check_dims=check_dims,
    385       input_derivative=INPUT_DERIVATIVE.DefaultOne,
--> 386       verbose=verbose)
    387 
    388 

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff(func, wrt, optimized, motion, mode, preserve_result, check_dims, input_derivative, verbose)
    288   # Generate the derivative
    289   node, namespace = autodiff_tree(func, wrt, motion, mode, preserve_result,
--> 290                                   check_dims, verbose)
    291 
    292   if mode == 'reverse' and motion == 'joint':

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff_tree(func, wrt, motion, mode, preserve_result, check_dims, verbose)
    142 
    143   node, required = autodiff_ast(func, wrt, motion, mode, preserve_result,
--> 144                                 check_dims, verbose)
    145   final.body.extend(node.body)
    146 

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff_ast(func, wrt, motion, mode, preserve_result, check_dims, verbose)
     87         for the returned function to run.
     88   """
---> 89   node = annotate.resolve_calls(func)
     90   fence.validate(node, inspect.getsource(func))
     91   node = anf_.anf(node)

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve_calls(func)
    108   """
    109   node = quoting.parse_function(func)
--> 110   ResolveCalls(func).visit(node)
    111   return node
    112 

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node)
    251         method = 'visit_' + node.__class__.__name__
    252         visitor = getattr(self, method, self.generic_visit)
--> 253         return visitor(node)
    254 
    255     def generic_visit(self, node):

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node)
    259                 for item in value:
    260                     if isinstance(item, AST):
--> 261                         self.visit(item)
    262             elif isinstance(value, AST):
    263                 self.visit(value)

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node)
    251         method = 'visit_' + node.__class__.__name__
    252         visitor = getattr(self, method, self.generic_visit)
--> 253         return visitor(node)
    254 
    255     def generic_visit(self, node):

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in visit_FunctionDef(self, node)
     43 
     44   def visit_FunctionDef(self, node):
---> 45     self.generic_visit(node)
     46     anno.setanno(node, 'func', self.func)
     47 

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node)
    259                 for item in value:
    260                     if isinstance(item, AST):
--> 261                         self.visit(item)
    262             elif isinstance(value, AST):
    263                 self.visit(value)

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node)
    251         method = 'visit_' + node.__class__.__name__
    252         visitor = getattr(self, method, self.generic_visit)
--> 253         return visitor(node)
    254 
    255     def generic_visit(self, node):

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node)
    259                 for item in value:
    260                     if isinstance(item, AST):
--> 261                         self.visit(item)
    262             elif isinstance(value, AST):
    263                 self.visit(value)

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node)
    251         method = 'visit_' + node.__class__.__name__
    252         visitor = getattr(self, method, self.generic_visit)
--> 253         return visitor(node)
    254 
    255     def generic_visit(self, node):

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node)
    261                         self.visit(item)
    262             elif isinstance(value, AST):
--> 263                 self.visit(value)
    264 
    265 

/shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node)
    251         method = 'visit_' + node.__class__.__name__
    252         visitor = getattr(self, method, self.generic_visit)
--> 253         return visitor(node)
    254 
    255     def generic_visit(self, node):

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in visit_Call(self, node)
     64                     node.id, self.func.__name__))
     65 
---> 66     func = resolve(node.func)
     67     # If the user has used the @tangent.trace decorator,
     68     # then we'll switch to tracing the function.

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve(node)
     51     def resolve(node):
     52       if isinstance(node, gast.Attribute):
---> 53         return getattr(resolve(node.value), node.attr)
     54       if isinstance(node, gast.Name):
     55         if node.id in self.namespace:

/shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve(node)
     62             raise AttributeError(
     63                 'Failed to resolve name "%s" used by "%s".'% (
---> 64                     node.id, self.func.__name__))
     65 
     66     func = resolve(node.func)

AttributeError: Failed to resolve name "x" used by "test".
alexbw commented 6 years ago

Hi Stefan, this is a case where we should provide a better error message, but the function test has no gradient, since it has no arguments.

On Fri, Feb 23, 2018 at 5:07 AM Stefan Doerr notifications@github.com wrote:

def test(): x = [] for i in range(5): x.append(i) return x

In [10]: xxx = tangent.grad(test)

AttributeError Traceback (most recent call last)

in () ----> 1 xxx = tangent.grad(test) /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in grad(func, wrt, optimized, preserve_result, check_dims, verbose) 384 check_dims=check_dims, 385 input_derivative=INPUT_DERIVATIVE.DefaultOne, --> 386 verbose=verbose) 387 388 /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff(func, wrt, optimized, motion, mode, preserve_result, check_dims, input_derivative, verbose) 288 # Generate the derivative 289 node, namespace = autodiff_tree(func, wrt, motion, mode, preserve_result, --> 290 check_dims, verbose) 291 292 if mode == 'reverse' and motion == 'joint': /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff_tree(func, wrt, motion, mode, preserve_result, check_dims, verbose) 142 143 node, required = autodiff_ast(func, wrt, motion, mode, preserve_result, --> 144 check_dims, verbose) 145 final.body.extend(node.body) 146 /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/grad_util.py in autodiff_ast(func, wrt, motion, mode, preserve_result, check_dims, verbose) 87 for the returned function to run. 88 """ ---> 89 node = annotate.resolve_calls(func) 90 fence.validate(node, inspect.getsource(func)) 91 node = anf_.anf(node) /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve_calls(func) 108 """ 109 node = quoting.parse_function(func) --> 110 ResolveCalls(func).visit(node) 111 return node 112 /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node) 251 method = 'visit_' + node.__class__.__name__ 252 visitor = getattr(self, method, self.generic_visit) --> 253 return visitor(node) 254 255 def generic_visit(self, node): /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node) 259 for item in value: 260 if isinstance(item, AST): --> 261 self.visit(item) 262 elif isinstance(value, AST): 263 self.visit(value) /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node) 251 method = 'visit_' + node.__class__.__name__ 252 visitor = getattr(self, method, self.generic_visit) --> 253 return visitor(node) 254 255 def generic_visit(self, node): /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in visit_FunctionDef(self, node) 43 44 def visit_FunctionDef(self, node): ---> 45 self.generic_visit(node) 46 anno.setanno(node, 'func', self.func) 47 /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node) 259 for item in value: 260 if isinstance(item, AST): --> 261 self.visit(item) 262 elif isinstance(value, AST): 263 self.visit(value) /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node) 251 method = 'visit_' + node.__class__.__name__ 252 visitor = getattr(self, method, self.generic_visit) --> 253 return visitor(node) 254 255 def generic_visit(self, node): /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node) 259 for item in value: 260 if isinstance(item, AST): --> 261 self.visit(item) 262 elif isinstance(value, AST): 263 self.visit(value) /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node) 251 method = 'visit_' + node.__class__.__name__ 252 visitor = getattr(self, method, self.generic_visit) --> 253 return visitor(node) 254 255 def generic_visit(self, node): /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in generic_visit(self, node) 261 self.visit(item) 262 elif isinstance(value, AST): --> 263 self.visit(value) 264 265 /shared/sdoerr/Software/miniconda3/lib/python3.6/ast.py in visit(self, node) 251 method = 'visit_' + node.__class__.__name__ 252 visitor = getattr(self, method, self.generic_visit) --> 253 return visitor(node) 254 255 def generic_visit(self, node): /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in visit_Call(self, node) 64 node.id, self.func.__name__)) 65 ---> 66 func = resolve(node.func) 67 # If the user has used the @tangent.trace decorator, 68 # then we'll switch to tracing the function. /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve(node) 51 def resolve(node): 52 if isinstance(node, gast.Attribute): ---> 53 return getattr(resolve(node.value), node.attr) 54 if isinstance(node, gast.Name): 55 if node.id in self.namespace: /shared/sdoerr/Software/miniconda3/lib/python3.6/site-packages/tangent/annotate.py in resolve(node) 62 raise AttributeError( 63 'Failed to resolve name "%s" used by "%s".'% ( ---> 64 node.id, self.func.__name__)) 65 66 func = resolve(node.func) AttributeError: Failed to resolve name "x" used by "test". — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub , or mute the thread .