def visit_Call(self, node): full_name = str(anno.getanno(node.func, anno.Basic.QN, default='')) function_context_name = self.state[_Function].context_name node = self.generic_visit(node) # TODO(mdan): Refactor converted_call as a 'Call' operator. # Calls to the internal 'ag__' module are never converted (though their # arguments might be). if full_name.startswith('ag__.'): return node # Calls to the function context manager (inserted by function_scopes) are # also safe. if full_name.startswith(function_context_name + '.'): return node # Calls to pdb.set_trace or ipdb.set_trace are never converted. We don't use # the normal mechanisms to bypass these literals because they are sensitive # to the frame they are being called from. # TODO(mdan): Generalize this to a "static allowlist" config. if full_name in ('pdb.set_trace', 'ipdb.set_trace', 'breakpoint'): global set_trace_warned if not set_trace_warned: # TODO(mdan): Update and shorten once available on tensorflow.org. ag_logging.warning( 'Detected `pdb.set_trace()` in user code. The code' ' generated by AutoGraph is not optimized for step-by-step' ' debugging. See https://github.com/tensorflow/tensorflow/' 'blob/master/tensorflow/python/autograph/g3doc/reference/' 'debugging.md.') set_trace_warned = True return node if (full_name == 'print' and not self.ctx.user.options.uses( converter.Feature.BUILTIN_FUNCTIONS)): return node template = """ ag__.converted_call(func, args, kwargs, function_ctx) """ new_call = templates.replace_as_expression( template, func=node.func, args=self._args_to_tuple(node), kwargs=self._kwargs_to_dict(node), function_ctx=function_context_name) return new_call
def is_unsupported(o): """Checks whether an entity is supported by AutoGraph at all.""" # TODO(b/122265385): Remove this bypass. if (_is_known_loaded_type(o, 'wrapt', 'FunctionWrapper') or _is_known_loaded_type(o, 'wrapt', 'BoundFunctionWrapper')): logging.warning( '{} appears to be decorated by wrapt, which is not yet supported' ' by AutoGraph. The function will run as-is.' ' You may still apply AutoGraph before the wrapt decorator.'. format(o)) logging.log(2, 'Permanently allowed: %s: wrapt decorated', o) return True if _is_known_loaded_type(o, 'functools', '_lru_cache_wrapper'): logging.log(2, 'Permanently allowed: %s: lru_cache', o) return True # Constructors are permanently allowed. # TODO(mdan): Toggle as experimental feature instead. # TODO(b/124016764): Remove this limitation. if inspect_utils.isconstructor(o): logging.log(2, 'Permanently allowed: %s: constructor', o) return True # Other built-in modules are permanently allowed. # TODO(mdan): Figure out how to do this consistently for all stdlib modules. if any( _is_of_known_loaded_module(o, m) for m in ('collections', 'pdb', 'copy', 'inspect', 're')): logging.log(2, 'Permanently allowed: %s: part of builtin module', o) return True # Custom ops and kernels are also permanently allowed. # See tensorflow.framework.load_library. if (hasattr(o, '__module__') and hasattr(o.__module__, '_IS_TENSORFLOW_PLUGIN')): logging.log(2, 'Permanently allowed: %s: TensorFlow plugin', o) return True return False
def _verify_inefficient_unroll(self): """Checks for possibly-inefficient creation of ops in a Python loop.""" assert self.ops_before_iteration is not None ops_after_iteration = self._get_ops() new_ops = tuple( op for op in ops_after_iteration if op not in self.ops_before_iteration) if len(new_ops) < INEFFICIENT_UNROLL_MIN_OPS: return False ag_logging.warning( 'Large unrolled loop detected. Did you mean to use a TF loop?' ' The following ops were created after iteration %s: %s' '\nSee' ' https://github.com/tensorflow/tensorflow/blob/master/' 'tensorflow/python/autograph/g3doc/reference/common_errors.md' '#warning-large-unrolled-loop-detected' '\n' 'Location:' '\n%s' '', self.iterations, new_ops, '\n'.join(traceback.format_stack())) return True
def _fall_back_unconverted(f, args, kwargs, options, exc): """Falls back to calling the function unconverted, in case of error.""" # TODO(mdan): Consider adding an internal metric. warning_template = ( 'AutoGraph could not transform %s and will run it as-is.\n' '%s' 'Cause: %s\n' 'To silence this warning, decorate the function with' ' @tf.autograph.experimental.do_not_convert') if isinstance(exc, errors.InaccessibleSourceCodeError): if ag_ctx.INSPECT_SOURCE_SUPPORTED: logging.warning(warning_template, f, '', exc) elif isinstance(exc, errors.UnsupportedLanguageElementError): if not conversion.is_in_allowlist_cache(f, options): logging.warning(warning_template, f, '', exc) else: file_bug_message = ( 'Please report this to the TensorFlow team. When filing the bug, set' ' the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and' ' attach the full output.\n') logging.warning(warning_template, f, file_bug_message, exc) return _call_unconverted(f, args, kwargs, options)
def __exit__(self, unused_type, unused_value, unused_traceback): assert _control_ctx()[-1] is self _control_ctx().pop() class NullCtx(object): """Helper substitute for contextlib.nullcontext.""" def __enter__(self): pass def __exit__(self, unused_type, unused_value, unused_traceback): pass def _default_control_status_ctx(): return ControlStatusCtx(status=Status.UNSPECIFIED) INSPECT_SOURCE_SUPPORTED = True try: inspect.getsource(ag_logging.log) except OSError: INSPECT_SOURCE_SUPPORTED = False ag_logging.warning( 'AutoGraph is not available in this environment: functions lack code' ' information. This is typical of some environments like the interactive' ' Python shell. See' ' https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/g3doc/reference/limitations.md#access-to-source-code' ' for more information.')