diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ca92288e93c2d237f02badeb54198f149928096 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/asserts.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/asserts.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8107ca2e4fe894c4e7e1a06b289ae7d5c9c1d0aa Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/asserts.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/break_statements.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/break_statements.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d744aa507dfd116fecdb9c81422ebef1550ddbf Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/break_statements.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/call_trees.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/call_trees.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f76e662785ccfb8af3eaca065cc85506d97b2c64 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/call_trees.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/conditional_expressions.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/conditional_expressions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d4cd393bdc7f7a3fc9d729492290922225df083 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/conditional_expressions.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/continue_statements.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/continue_statements.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f4b1e08e67c7b59b379c17cb708e81b48605b7f Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/continue_statements.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/control_flow.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/control_flow.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8c944c44461202afce8cc9de4fb589b8c4d635b Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/control_flow.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/directives.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/directives.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2819a2eed9f08c41984fbe2bb06569110557ec4 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/directives.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/functions.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/functions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34cc0bcb428b30e91f3f228d0d6cfae117f9f771 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/functions.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/lists.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/lists.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..898954247988a56415a99f662a4b33e416b3853e Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/lists.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/logical_expressions.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/logical_expressions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da15feb07e5ab9457ed8e695bcd8bda230284e7c Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/logical_expressions.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/return_statements.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/return_statements.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78e65015d5b73c668242fceda45e4544124983ea Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/return_statements.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/slices.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/slices.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a4a53a99de1502902755fe7b66e520b4768c74a Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/slices.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/variables.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/variables.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a09c4eb003badec967c3338355bbb31f7cfeed0b Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/variables.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/asserts.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/asserts.py new file mode 100644 index 0000000000000000000000000000000000000000..68f20a7fca5a666fb559c8f64428ec3fc8ed1fcc --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/asserts.py @@ -0,0 +1,48 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converts assert statements to their corresponding TF calls.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import templates + + +class AssertTransformer(converter.Base): + """Transforms Assert nodes to Call so they can be handled as functions.""" + + def visit_Assert(self, node): + self.generic_visit(node) + + # Note: The lone tf.Assert call will be wrapped with control_dependencies + # by side_effect_guards. + template = """ + ag__.assert_stmt(test, lambda: msg) + """ + + if node.msg is None: + return templates.replace( + template, + test=node.test, + msg=gast.Constant('Assertion error', kind=None)) + elif isinstance(node.msg, gast.Constant): + return templates.replace(template, test=node.test, msg=node.msg) + else: + raise NotImplementedError('can only convert string messages for now.') + + +def transform(node, ctx): + node = AssertTransformer(ctx).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/break_statements.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/break_statements.py new file mode 100644 index 0000000000000000000000000000000000000000..f91c943f2145ef4c7ea6b10dce7fd1cf0d56a7bd --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/break_statements.py @@ -0,0 +1,185 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Lowers break statements to conditionals.""" + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno + + +class _Break(object): + + def __init__(self): + self.used = False + self.control_var_name = None + + def __repr__(self): + return 'used: %s, var: %s' % (self.used, self.control_var_name) + + +class BreakTransformer(converter.Base): + """Canonicalizes break statements into additional conditionals.""" + + def visit_Break(self, node): + self.state[_Break].used = True + var_name = self.state[_Break].control_var_name + # TODO(mdan): This will fail when expanded inside a top-level else block. + template = """ + var_name = True + continue + """ + return templates.replace(template, var_name=var_name) + + def _guard_if_present(self, block, var_name): + """Prevents the block from executing if var_name is set.""" + if not block: + return block + + template = """ + if not var_name: + block + """ + node = templates.replace( + template, + var_name=var_name, + block=block) + return node + + def _process_body(self, nodes, break_var): + self.state[_Break].enter() + self.state[_Break].control_var_name = break_var + nodes = self.visit_block(nodes) + break_used = self.state[_Break].used + self.state[_Break].exit() + return nodes, break_used + + def visit_While(self, node): + original_node = node + scope = anno.getanno(node, NodeAnno.BODY_SCOPE) + break_var = self.ctx.namer.new_symbol('break_', scope.referenced) + + node.test = self.visit(node.test) + node.body, break_used = self._process_body(node.body, break_var) + # A break in the else clause applies to the containing scope. + node.orelse = self.visit_block(node.orelse) + + if not break_used: + template = """ + while test: + body + orelse + """ + node = templates.replace( + template, test=node.test, body=node.body, orelse=node.orelse) + + new_while_node = node[0] + anno.copyanno(original_node, new_while_node, anno.Basic.DIRECTIVES) + + return node + + # Python's else clause only triggers if the loop exited cleanly (e.g. + # break did not trigger). + guarded_orelse = self._guard_if_present(node.orelse, break_var) + + template = """ + var_name = False + while not var_name and test: + body + orelse + """ + node = templates.replace( + template, + var_name=break_var, + test=node.test, + body=node.body, + orelse=guarded_orelse) + + new_while_node = node[1] + anno.copyanno(original_node, new_while_node, anno.Basic.DIRECTIVES) + + return node + + def visit_For(self, node): + original_node = node + scope = anno.getanno(node, NodeAnno.BODY_SCOPE) + break_var = self.ctx.namer.new_symbol('break_', scope.referenced) + + node.target = self.visit(node.target) + node.iter = self.visit(node.iter) + node.body, break_used = self._process_body(node.body, break_var) + # A break in the else clause applies to the containing scope. + node.orelse = self.visit_block(node.orelse) + + if not break_used: + template = """ + for target in iter_: + body + orelse + """ + node = templates.replace( + template, + iter_=node.iter, + target=node.target, + body=node.body, + orelse=node.orelse) + + new_for_node = node[0] + anno.copyanno(original_node, new_for_node, anno.Basic.EXTRA_LOOP_TEST) + anno.copyanno(original_node, new_for_node, anno.Basic.DIRECTIVES) + + return node + + # Python's else clause only triggers if the loop exited cleanly (e.g. + # break did not trigger). + guarded_orelse = self._guard_if_present(node.orelse, break_var) + extra_test = templates.replace_as_expression( + 'not var_name', var_name=break_var) + + # The extra test is hidden in the AST, which will confuse the static + # analysis. To mitigate that, we insert a no-op statement that ensures + # the control variable is marked as used. + # TODO(mdan): Use a marker instead, e.g. ag__.condition_loop_on(var_name) + template = """ + var_name = False + for target in iter_: + (var_name,) + body + orelse + """ + node = templates.replace( + template, + var_name=break_var, + iter_=node.iter, + target=node.target, + body=node.body, + orelse=guarded_orelse) + + new_for_node = node[1] + anno.setanno(new_for_node, anno.Basic.EXTRA_LOOP_TEST, extra_test) + anno.copyanno(original_node, new_for_node, anno.Basic.DIRECTIVES) + + return node + + +def transform(node, ctx): + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + + transformer = BreakTransformer(ctx) + node = transformer.visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/call_trees.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/call_trees.py new file mode 100644 index 0000000000000000000000000000000000000000..3d694d45a17b0b7b9d8fc9a256020b81779f8924 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/call_trees.py @@ -0,0 +1,221 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Handles function calls, by generating compiled function names and calls. + +Note: this transformer does not rename the top level object being converted; +that is the caller's responsibility. + +Requires function_scopes. +""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.utils import ag_logging + + +# TODO(mdan): Rename to FunctionCallsTransformer. + + +class _Function(object): + + no_root = True + + def __init__(self): + self.context_name = None + + +set_trace_warned = False + + +class _ArgTemplateBuilder(object): + """Constructs a tuple representing the positional arguments in a call. + + Example (yes, it's legal Python 3): + + f(*args1, b, *args2, c, d) -> args1 + (b,) + args2 + (c, d) + """ + + def __init__(self): + self._arg_accumulator = [] + self._argspec = [] + self._finalized = False + + def _consume_args(self): + if self._arg_accumulator: + self._argspec.append( + gast.Tuple(elts=self._arg_accumulator, ctx=gast.Load())) + self._arg_accumulator = [] + + def add_arg(self, a): + self._arg_accumulator.append(a) + + def add_stararg(self, a): + self._consume_args() + self._argspec.append( + gast.Call( + gast.Name( + 'tuple', ctx=gast.Load(), annotation=None, type_comment=None), + args=[a], + keywords=())) + + def finalize(self): + self._consume_args() + self._finalized = True + + def to_ast(self): + assert self._finalized + if self._argspec: + result = self._argspec[0] + for i in range(1, len(self._argspec)): + result = gast.BinOp(result, gast.Add(), self._argspec[i]) + return result + return gast.Tuple([], gast.Load()) + + +class CallTreeTransformer(converter.Base): + """Transforms the call tree by renaming transformed symbols.""" + + def visit_Lambda(self, node): + if not anno.hasanno(node, 'function_context_name'): + # Lambda functions created during the conversion process have no + # context manager. + return self.generic_visit(node) + with self.state[_Function] as fn_scope: + fn_scope.context_name = anno.getanno(node, 'function_context_name') + return self.generic_visit(node) + + def visit_FunctionDef(self, node): + # Decorators and arg defaults are part of the outer scope. + node.decorator_list = self.visit_block(node.decorator_list) + node.args.defaults = self.visit_block(node.args.defaults) + for i, d in enumerate(node.args.kw_defaults): + if d is not None: + node.args.kw_defaults[i] = self.visit(d) + with self.state[_Function] as fn_scope: + # Note: if the conversion process ever creates helper functions, this + # assumption will no longer hold. + assert anno.hasanno(node, 'function_context_name'), ( + 'The function_scopes converter always creates a scope for functions.') + fn_scope.context_name = anno.getanno(node, 'function_context_name') + node.body = self.visit_block(node.body) + if node.returns: + node.returns = self.visit(node.returns) + return node + + def visit_With(self, node): + # Context manager calls (in node.items) are not converted. + node.body = self.visit_block(node.body) + return node + + def _args_to_tuple(self, node): + """Ties together all positional and *arg arguments in a single tuple.""" + # TODO(mdan): We could rewrite this to just a call to tuple(). Maybe better? + # For example for + # f(a, b, *args) + # instead of writing: + # (a, b) + args + # just write this? + # tuple(a, b, *args) + builder = _ArgTemplateBuilder() + for a in node.args: + if isinstance(a, gast.Starred): + builder.add_stararg(a.value) + else: + builder.add_arg(a) + builder.finalize() + return builder.to_ast() + + def _kwargs_to_dict(self, node): + """Ties together all keyword and **kwarg arguments in a single dict.""" + if node.keywords: + return gast.Call( + gast.Name( + 'dict', ctx=gast.Load(), annotation=None, type_comment=None), + args=(), + keywords=node.keywords) + else: + return parser.parse_expression('None') + + 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 transform(node, ctx): + """Transform function call to the compiled counterparts. + + Args: + node: AST + ctx: EntityContext + Returns: + A tuple (node, new_names): + node: The transformed AST + new_names: set(string), containing any newly-generated names + """ + node = qual_names.resolve(node) + + node = CallTreeTransformer(ctx).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/conditional_expressions.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/conditional_expressions.py new file mode 100644 index 0000000000000000000000000000000000000000..d61a5cd8548eb097cc657ef5403c8699f643a857 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/conditional_expressions.py @@ -0,0 +1,46 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converts the ternary conditional operator.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import templates + + +class ConditionalExpressionTransformer(converter.Base): + """Converts conditional expressions to functional form.""" + + def visit_IfExp(self, node): + template = ''' + ag__.if_exp( + test, + lambda: true_expr, + lambda: false_expr, + expr_repr) + ''' + expr_repr = parser.unparse(node.test, include_encoding_marker=False).strip() + return templates.replace_as_expression( + template, + test=node.test, + true_expr=node.body, + false_expr=node.orelse, + expr_repr=gast.Constant(expr_repr, kind=None)) + + +def transform(node, ctx): + node = ConditionalExpressionTransformer(ctx).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/continue_statements.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/continue_statements.py new file mode 100644 index 0000000000000000000000000000000000000000..5b2854d9244d41c259d9ece4170131c534316fbd --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/continue_statements.py @@ -0,0 +1,164 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Canonicalizes continue statements by de-sugaring into a control boolean.""" + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno + + +class _Continue(object): + + def __init__(self): + self.used = False + self.control_var_name = None + + def __repr__(self): + return '<_Continue(used: {}, var: {})>'.format(self.used, + self.control_var_name) + + +class _Block(object): + """Tracks information about lexical blocks as they are visited in the AST. + + Mainly, this object tracks the creation of block guards that replace + `continue` statements (e.g. `if not continue_:`). + + Attributes: + create_guard_current: bool, whether to create a guard for the current + statement. + create_guard_next: bool, whether to create a guard for the next + statement. + is_loop_type: bool, whether this block is the body of a loop. + """ + + def __init__(self): + self.is_loop_type = False + self.create_guard_current = False + self.create_guard_next = False + + +class ContinueCanonicalizationTransformer(converter.Base): + """Canonicalizes continue statements into additional conditionals.""" + + def visit_Continue(self, node): + self.state[_Continue].used = True + for block in reversed(self.state[_Block].stack): + # See ContinueCanonicalizationTest.test_multiple_continues for an example + # it's necessary to create guards for all enclosing affected blocks, not + # just that of the current block. + block.create_guard_next = True + if block.is_loop_type: + # continue only affects the innermost loop + break + template = """ + var_name = True + """ + return templates.replace( + template, var_name=self.state[_Continue].control_var_name) + + def _postprocess_statement(self, node): + if self.state[_Continue].used: + block = self.state[_Block] + should_wrap_current = block.create_guard_current + # After processing propagate whether to guard the next statement + block.create_guard_current = block.create_guard_next + block.create_guard_next = False + if should_wrap_current: + template = """ + if not var_name: + original_node + """ + cond, = templates.replace( + template, + var_name=self.state[_Continue].control_var_name, + original_node=node) + return cond, cond.body + return node, None + + def _visit_loop_body(self, node, nodes): + self.state[_Continue].enter() + self.state[_Block].enter() + self.state[_Block].is_loop_type = True + scope = anno.getanno(node, NodeAnno.BODY_SCOPE) + continue_var = self.ctx.namer.new_symbol('continue_', scope.referenced) + self.state[_Continue].control_var_name = continue_var + + nodes = self.visit_block(nodes, after_visit=self._postprocess_statement) + + if self.state[_Continue].used: + template = """ + var_name = False + """ + control_var_init = templates.replace(template, var_name=continue_var) + nodes = control_var_init + nodes + + self.state[_Block].exit() + self.state[_Continue].exit() + return nodes + + def _visit_non_loop_body(self, nodes): + self.state[_Block].enter() + nodes = self.visit_block(nodes, after_visit=self._postprocess_statement) + self.state[_Block].exit() + return nodes + + def visit_While(self, node): + node.test = self.visit(node.test) + node.body = self._visit_loop_body(node, node.body) + # A continue in the else clause applies to the containing scope. + node.orelse = self._visit_non_loop_body(node.orelse) + return node + + def visit_For(self, node): + node.target = self.generic_visit(node.target) + node.iter = self.generic_visit(node.iter) + node.body = self._visit_loop_body(node, node.body) + # A continue in the else clause applies to the containing scope. + node.orelse = self._visit_non_loop_body(node.orelse) + return node + + def visit_If(self, node): + node.body = self._visit_non_loop_body(node.body) + node.orelse = self._visit_non_loop_body(node.orelse) + return node + + def visit_With(self, node): + node.items = self.visit_block(node.items) + node.body = self._visit_non_loop_body(node.body) + return node + + def visit_Try(self, node): + node.body = self._visit_non_loop_body(node.body) + node.orelse = self._visit_non_loop_body(node.orelse) + # In Python 3.8 and later continue is allowed in finally blocks + node.finalbody = self._visit_non_loop_body(node.finalbody) + node.handlers = self.visit_block(node.handlers) + return node + + def visit_ExceptHandler(self, node): + node.body = self._visit_non_loop_body(node.body) + return node + + +def transform(node, ctx): + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + + node = ContinueCanonicalizationTransformer(ctx).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/control_flow.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/control_flow.py new file mode 100644 index 0000000000000000000000000000000000000000..ad50d0338b12efd99de686dc35d765549c2b5d95 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/control_flow.py @@ -0,0 +1,413 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Handles control flow statements: while, for, if.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.lang import directives +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import origin_info +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis import annos +from tensorflow.python.autograph.pyct.static_analysis import liveness +from tensorflow.python.autograph.pyct.static_analysis import reaching_definitions +from tensorflow.python.autograph.pyct.static_analysis import reaching_fndefs + + +class _Function(object): + + scope = None + + +class ControlFlowTransformer(converter.Base): + """Transforms control flow structures like loops an conditionals.""" + + def visit_Lambda(self, node): + with self.state[_Function] as fn: + fn.scope = anno.getanno(node, anno.Static.SCOPE) + return self.generic_visit(node) + + def visit_FunctionDef(self, node): + with self.state[_Function] as fn: + fn.scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE) + return self.generic_visit(node) + + def _create_nonlocal_declarations(self, vars_): + vars_ = set(vars_) + results = [] + global_vars = self.state[_Function].scope.globals & vars_ + + if global_vars: + results.append(gast.Global([str(v) for v in global_vars])) + + nonlocal_vars = [ + v for v in vars_ if not v.is_composite() and v not in global_vars] + if nonlocal_vars: + results.append(gast.Nonlocal([str(v) for v in nonlocal_vars])) + + return results + + def _create_state_functions( + self, block_vars, nonlocal_declarations, getter_name, setter_name): + if not block_vars: + template = """ + def getter_name(): + return () + def setter_name(block_vars): + pass + """ + return templates.replace( + template, getter_name=getter_name, setter_name=setter_name) + + guarded_block_vars = [] + for v in block_vars: + if v.is_simple(): + guarded_block_vars.append(v) + else: + guarded_block_vars.append( + templates.replace_as_expression( + 'ag__.ldu(lambda: var_, name)', + var_=v, + name=gast.Constant(str(v), kind=None))) + + template = """ + def getter_name(): + return guarded_state_vars, + def setter_name(vars_): + nonlocal_declarations + state_vars, = vars_ + """ + return templates.replace( + template, + nonlocal_declarations=nonlocal_declarations, + getter_name=getter_name, + guarded_state_vars=guarded_block_vars, + setter_name=setter_name, + state_vars=tuple(block_vars)) + + def _create_loop_options(self, node): + if not anno.hasanno(node, anno.Basic.DIRECTIVES): + return gast.Dict([], []) + + loop_directives = anno.getanno(node, anno.Basic.DIRECTIVES) + if directives.set_loop_options not in loop_directives: + return gast.Dict([], []) + + opts_dict = loop_directives[directives.set_loop_options] + str_keys, values = zip(*opts_dict.items()) + keys = [gast.Constant(s, kind=None) for s in str_keys] + values = list(values) # ast and gast don't play well with tuples. + return gast.Dict(keys, values) + + def _create_undefined_assigns(self, undefined_symbols): + assignments = [] + for s in undefined_symbols: + template = ''' + var = ag__.Undefined(symbol_name) + ''' + assignments += templates.replace( + template, + var=s, + symbol_name=gast.Constant(s.ssf(), kind=None)) + return assignments + + def _get_block_basic_vars(self, modified, live_in, live_out): + nonlocals = self.state[_Function].scope.nonlocals + basic_scope_vars = [] + for s in modified: + if s.is_composite(): + # TODO(mdan): Raise an error when this happens for a TF scope. + continue + # Variables not live into or out of the scope are considered local to the + # scope. + if s in live_in or s in live_out or s in nonlocals: + basic_scope_vars.append(s) + continue + return frozenset(basic_scope_vars) + + def _get_block_composite_vars(self, modified, live_in): + # The scope variables corresponding to composite symbols (e.g. `self.x`). + composite_scope_vars = [] + for s in modified: + if not s.is_composite(): + continue + # Mutations made to objects created inside the scope will appear as writes + # to composite symbols. Because these mutations appear as modifications + # made to composite symbols, we check whether the composite's parent is + # actually live into the scope. + # Example: + # while cond: + # x = Foo() + # x.foo = 2 * x.foo # x.foo is live into the scope, but x is not. + # + # Note that some parents might not be symbols - for example, in x['foo'], + # 'foo' is a parent, but it's a literal, not a symbol. We don't check the + # liveness of literals. + support_set_symbols = tuple( + sss for sss in s.support_set if sss.is_symbol()) + if not all(sss in live_in for sss in support_set_symbols): + continue + composite_scope_vars.append(s) + return frozenset(composite_scope_vars) + + def _get_block_vars(self, node, modified): + """Determines the variables affected inside a control flow statement.""" + defined_in = anno.getanno(node, anno.Static.DEFINED_VARS_IN) + live_in = anno.getanno(node, anno.Static.LIVE_VARS_IN) + live_out = anno.getanno(node, anno.Static.LIVE_VARS_OUT) + fn_scope = self.state[_Function].scope + + basic_scope_vars = self._get_block_basic_vars( + modified, + live_in, + live_out) + composite_scope_vars = self._get_block_composite_vars(modified, live_in) + scope_vars = tuple(basic_scope_vars | composite_scope_vars) + + # Variables that are modified inside the scope, but not defined + # before entering it. Only simple variables must be defined. The + # composite ones will be implicitly checked at runtime. + possibly_undefined = ( + modified - defined_in - fn_scope.globals - fn_scope.nonlocals) + undefined = tuple(v for v in possibly_undefined if not v.is_composite()) + + # Variables that are modified inside the scope, and depend on values outside + # it. + input_only = basic_scope_vars & live_in - live_out + + # Place the outputs first, then sort lexicographically. + scope_vars = sorted(scope_vars, key=lambda v: (v in input_only, v)) + nouts = len(scope_vars) - len(input_only) + + return scope_vars, undefined, nouts + + def visit_If(self, node): + node = self.generic_visit(node) + body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE) + orelse_scope = anno.getanno(node, annos.NodeAnno.ORELSE_SCOPE) + + cond_vars, undefined, nouts = self._get_block_vars( + node, body_scope.bound | orelse_scope.bound) + + undefined_assigns = self._create_undefined_assigns(undefined) + + nonlocal_declarations = self._create_nonlocal_declarations(cond_vars) + + reserved = body_scope.referenced | orelse_scope.referenced + state_getter_name = self.ctx.namer.new_symbol('get_state', reserved) + state_setter_name = self.ctx.namer.new_symbol('set_state', reserved) + state_functions = self._create_state_functions( + cond_vars, nonlocal_declarations, state_getter_name, state_setter_name) + + orelse_body = node.orelse + if not orelse_body: + orelse_body = [gast.Pass()] + + template = """ + state_functions + def body_name(): + nonlocal_declarations + body + def orelse_name(): + nonlocal_declarations + orelse + undefined_assigns + ag__.if_stmt( + test, + body_name, + orelse_name, + state_getter_name, + state_setter_name, + (symbol_names,), + nouts) + """ + new_nodes = templates.replace( + template, + body=node.body, + body_name=self.ctx.namer.new_symbol('if_body', reserved), + orelse=orelse_body, + orelse_name=self.ctx.namer.new_symbol('else_body', reserved), + nonlocal_declarations=nonlocal_declarations, + nouts=gast.Constant(nouts, kind=None), + state_functions=state_functions, + state_getter_name=state_getter_name, + state_setter_name=state_setter_name, + symbol_names=tuple(gast.Constant(str(s), kind=None) for s in cond_vars), + test=node.test, + undefined_assigns=undefined_assigns) + origin_info.copy_origin(node, new_nodes[-1]) + return new_nodes + + def visit_While(self, node): + node = self.generic_visit(node) + body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE) + + loop_vars, undefined, _ = self._get_block_vars(node, body_scope.bound) + + undefined_assigns = self._create_undefined_assigns(undefined) + + nonlocal_declarations = self._create_nonlocal_declarations(loop_vars) + + reserved = body_scope.referenced + state_getter_name = self.ctx.namer.new_symbol('get_state', reserved) + state_setter_name = self.ctx.namer.new_symbol('set_state', reserved) + state_functions = self._create_state_functions( + loop_vars, nonlocal_declarations, state_getter_name, state_setter_name) + + opts = self._create_loop_options(node) + + template = """ + state_functions + def body_name(): + nonlocal_declarations + body + def test_name(): + return test + undefined_assigns + ag__.while_stmt( + test_name, + body_name, + state_getter_name, + state_setter_name, + (symbol_names,), + opts) + """ + new_nodes = templates.replace( + template, + body=node.body, + body_name=self.ctx.namer.new_symbol('loop_body', reserved), + nonlocal_declarations=nonlocal_declarations, + opts=opts, + state_functions=state_functions, + state_getter_name=state_getter_name, + state_setter_name=state_setter_name, + symbol_names=tuple(gast.Constant(str(s), kind=None) for s in loop_vars), + test=node.test, + test_name=self.ctx.namer.new_symbol('loop_test', reserved), + undefined_assigns=undefined_assigns) + origin_info.copy_origin(node, new_nodes[-1]) + return new_nodes + + def visit_For(self, node): + node = self.generic_visit(node) + body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE) + iter_scope = anno.getanno(node, annos.NodeAnno.ITERATE_SCOPE) + + loop_vars, undefined, _ = self._get_block_vars( + node, body_scope.bound | iter_scope.bound) + + undefined_assigns = self._create_undefined_assigns(undefined) + + nonlocal_declarations = self._create_nonlocal_declarations(loop_vars) + + reserved = body_scope.referenced | iter_scope.referenced + state_getter_name = self.ctx.namer.new_symbol('get_state', reserved) + state_setter_name = self.ctx.namer.new_symbol('set_state', reserved) + state_functions = self._create_state_functions( + loop_vars, nonlocal_declarations, state_getter_name, state_setter_name) + + opts = self._create_loop_options(node) + opts.keys.append(gast.Constant('iterate_names', kind=None)) + opts.values.append(gast.Constant( + parser.unparse(node.target, include_encoding_marker=False), kind=None)) + + if anno.hasanno(node, anno.Basic.EXTRA_LOOP_TEST): + extra_test = anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST) + extra_test_name = self.ctx.namer.new_symbol( + 'extra_test', reserved) + template = """ + def extra_test_name(): + nonlocal_declarations + return extra_test_expr + """ + extra_test_function = templates.replace( + template, + extra_test_expr=extra_test, + extra_test_name=extra_test_name, + loop_vars=loop_vars, + nonlocal_declarations=nonlocal_declarations) + else: + extra_test_name = parser.parse_expression('None') + extra_test_function = [] + + # iterate_arg_name holds a single arg with the iterates, which may be a + # tuple. + iterate_arg_name = self.ctx.namer.new_symbol('itr', reserved) + template = """ + iterates = iterate_arg_name + """ + iterate_expansion = templates.replace( + template, iterate_arg_name=iterate_arg_name, iterates=node.target) + origin_info.copy_origin(node, iterate_expansion) + + template = """ + state_functions + def body_name(iterate_arg_name): + nonlocal_declarations + iterate_expansion + body + extra_test_function + undefined_assigns + ag__.for_stmt( + iterated, + extra_test_name, + body_name, + state_getter_name, + state_setter_name, + (symbol_names,), + opts) + """ + new_nodes = templates.replace( + template, + body=node.body, + body_name=self.ctx.namer.new_symbol('loop_body', reserved), + extra_test_function=extra_test_function, + extra_test_name=extra_test_name, + iterate_arg_name=iterate_arg_name, + iterate_expansion=iterate_expansion, + iterated=node.iter, + nonlocal_declarations=nonlocal_declarations, + opts=opts, + symbol_names=tuple(gast.Constant(str(s), kind=None) for s in loop_vars), + state_functions=state_functions, + state_getter_name=state_getter_name, + state_setter_name=state_setter_name, + undefined_assigns=undefined_assigns) + origin_info.copy_origin(node, new_nodes[-1]) + return new_nodes + + +class AnnotatedDef(reaching_definitions.Definition): + + def __init__(self): + super(AnnotatedDef, self).__init__() + self.directives = {} + + +def transform(node, ctx): + graphs = cfg.build(node) + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + node = reaching_definitions.resolve(node, ctx, graphs) + node = reaching_fndefs.resolve(node, ctx, graphs) + node = liveness.resolve(node, ctx, graphs) + + node = ControlFlowTransformer(ctx).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/directives.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/directives.py new file mode 100644 index 0000000000000000000000000000000000000000..8e1955d9b85ec622ced6268b77856f2572e3b65a --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/directives.py @@ -0,0 +1,177 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Handles directives. + +This converter removes the directive functions from the code and moves the +information they specify into AST annotations. It is a specialized form of +static analysis, one that is specific to AutoGraph. + +Note that this requires that the actual directive functions are static - that +is, they do not change at runtime. So if you do something like this: + + tf.autograph.set_loop_options = + +Then the directive will may no longer be recognized. Furthermore, if the +converted function is cached, such an action may be irreversible. +""" + +import inspect + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.lang import directives +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.util import tf_inspect + + +STATIC_VALUE = 'static_value' +"""Used for AST annotations, see visit_Name.""" + + +class _LoopScope(object): + + def __init__(self): + self.ast_node = None + self.statements_visited = 0 + + +def _map_args(call_node, function): + """Maps AST call nodes to the actual function's arguments. + + Args: + call_node: ast.Call + function: Callable[..., Any], the actual function matching call_node + Returns: + Dict[Text, ast.AST], mapping each of the function's argument names to + the respective AST node. + Raises: + ValueError: if the default arguments are not correctly set + """ + args = call_node.args + kwds = {kwd.arg: kwd.value for kwd in call_node.keywords} + call_args = tf_inspect.getcallargs(function, *args, **kwds) + + # Keyword arguments not specified in kwds will be mapped to their defaults, + # which are Python values. Since we don't currently have a way to transform + # those into AST references, we simply remove them. By convention, directives + # use UNSPECIFIED as default value for optional arguments. No other + # defaults should be present. + unexpected_defaults = [] + for k in call_args: + if (k not in kwds + and call_args[k] not in args + and call_args[k] is not directives.UNSPECIFIED): + unexpected_defaults.append(k) + if unexpected_defaults: + raise ValueError('Unexpected keyword argument values, %s, for function %s' + % (zip(unexpected_defaults, + [call_args[k] for k in unexpected_defaults]), + function)) + return {k: v for k, v in call_args.items() if v is not directives.UNSPECIFIED} + + +class DirectivesTransformer(converter.Base): + """Parses compiler directives and converts them into AST annotations.""" + + def _process_symbol_directive(self, call_node, directive): + if len(call_node.args) < 1: + raise ValueError('"%s" requires a positional first argument' + ' as the target' % directive.__name__) + target = call_node.args[0] + defs = anno.getanno(target, anno.Static.ORIG_DEFINITIONS) + for def_ in defs: + def_.directives[directive] = _map_args(call_node, directive) + return call_node + + def _process_statement_directive(self, call_node, directive): + if self.state[_LoopScope].statements_visited > 1: + raise ValueError( + '"%s" must be the first statement in the loop block' % ( + directive.__name__)) + if self.state[_LoopScope].level < 2: + raise ValueError( + '"%s" must be used inside a statement' % directive.__name__) + target = self.state[_LoopScope].ast_node + node_anno = anno.getanno(target, anno.Basic.DIRECTIVES, {}) + node_anno[directive] = _map_args(call_node, directive) + anno.setanno(target, anno.Basic.DIRECTIVES, node_anno) + return call_node + + def visit_Name(self, node): + node = self.generic_visit(node) + if isinstance(node.ctx, gast.Load): + defs = anno.getanno(node, anno.Static.DEFINITIONS, ()) + is_defined = bool(defs) + if not is_defined and node.id in self.ctx.info.namespace: + anno.setanno(node, STATIC_VALUE, self.ctx.info.namespace[node.id]) + return node + + def visit_Attribute(self, node): + node = self.generic_visit(node) + parent_val = anno.getanno(node.value, STATIC_VALUE, default=None) + if parent_val is not None and inspect.ismodule(parent_val): + if hasattr(parent_val, node.attr): + anno.setanno(node, STATIC_VALUE, getattr(parent_val, node.attr)) + return node + + def visit_Assign(self, node): + self.state[_LoopScope].statements_visited += 1 + return self.generic_visit(node) + + def visit_AugAssign(self, node): + self.state[_LoopScope].statements_visited += 1 + return self.generic_visit(node) + + def visit_Expr(self, node): + self.state[_LoopScope].statements_visited += 1 + node = self.generic_visit(node) + if isinstance(node.value, gast.Call): + call_node = node.value + static_val = anno.getanno(call_node.func, STATIC_VALUE, default=None) + if static_val is not None: + # Note: directive calls are not output in the generated code, hence + # the removal from the code by returning None. + + if static_val is directives.set_element_type: + self._process_symbol_directive(call_node, static_val) + return None + elif static_val is directives.set_loop_options: + self._process_statement_directive(call_node, static_val) + return None + return node + + # TODO(mdan): This will be insufficient for other control flow. + # That means that if we ever have a directive that affects things other than + # loops, we'll need support for parallel scopes, or have multiple converters. + def _track_and_visit_loop(self, node): + self.state[_LoopScope].enter() + self.state[_LoopScope].ast_node = node + node = self.generic_visit(node) + # Edge case: a loop with just one directive statement would become empty. + if not node.body: + node.body = [gast.Pass()] + self.state[_LoopScope].exit() + return node + + def visit_While(self, node): + return self._track_and_visit_loop(node) + + def visit_For(self, node): + return self._track_and_visit_loop(node) + + +def transform(node, ctx): + return DirectivesTransformer(ctx).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/functions.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/functions.py new file mode 100644 index 0000000000000000000000000000000000000000..72c5b5eac7884f0e86cd5b3a422c00923a7e1c24 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/functions.py @@ -0,0 +1,134 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converts function definitions and lambdas by adding necessary boilerplate.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis import annos + + +class _Function(object): + + def __init__(self): + self.context_name = None + + +class FunctionTransformer(converter.Base): + """Wraps function bodies around autograph-specific boilerplate.""" + + def _function_scope_options(self, fn_scope): + """Returns the options with which to create function scopes.""" + # Top-level function receive the options that were directly requested. + # All others receive the options corresponding to a recursive conversion. + # Note: this mainly controls the user_requested flag, which is important + # primarily because the FunctionScope context also creates a + # ControlStatusCtx(autograph=ENABLED) when user_requested is True. See + # function_wrappers.py. + if fn_scope.level == 2: + return self.ctx.user.options + return self.ctx.user.options.call_options() + + def visit_Lambda(self, node): + with self.state[_Function] as fn_scope: + node = self.generic_visit(node) + + # TODO(mdan): Fix the tests so that we can always add this decorator. + if fn_scope.level > 2: + return templates.replace_as_expression( + 'ag__.autograph_artifact(l)', l=node) + + scope = anno.getanno(node, anno.Static.SCOPE) + function_context_name = self.ctx.namer.new_symbol('lscope', + scope.referenced) + fn_scope.context_name = function_context_name + anno.setanno(node, 'function_context_name', function_context_name) + + template = """ + ag__.with_function_scope( + lambda function_context: body, function_context_name, options) + """ + node.body = templates.replace_as_expression( + template, + options=self._function_scope_options(fn_scope).to_ast(), + function_context=function_context_name, + function_context_name=gast.Constant(function_context_name, kind=None), + body=node.body) + + return node + + def visit_FunctionDef(self, node): + with self.state[_Function] as fn_scope: + scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE) + + function_context_name = self.ctx.namer.new_symbol('fscope', + scope.referenced) + fn_scope.context_name = function_context_name + anno.setanno(node, 'function_context_name', function_context_name) + + node = self.generic_visit(node) + + if fn_scope.level <= 2: + # Top-level functions lose their decorator because the conversion is + # always just-in-time and by the time it happens the decorators are + # already set to be applied. + node.decorator_list = [] + else: + # TODO(mdan): Fix the tests so that we can always add this decorator. + # Inner functions are converted already, so we insert a decorator to + # prevent double conversion. Double conversion would work too, but this + # saves the overhead. + node.decorator_list.append( + parser.parse_expression('ag__.autograph_artifact')) + + docstring_node = None + if node.body: + first_statement = node.body[0] + if (isinstance(first_statement, gast.Expr) and + isinstance(first_statement.value, gast.Constant)): + docstring_node = first_statement + node.body = node.body[1:] + + template = """ + with ag__.FunctionScope( + function_name, context_name, options) as function_context: + body + """ + wrapped_body = templates.replace( + template, + function_name=gast.Constant(node.name, kind=None), + context_name=gast.Constant(function_context_name, kind=None), + options=self._function_scope_options(fn_scope).to_ast(), + function_context=function_context_name, + body=node.body) + + if docstring_node is not None: + wrapped_body = [docstring_node] + wrapped_body + + node.body = wrapped_body + + return node + + +def transform(node, ctx): + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + + return FunctionTransformer(ctx).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/lists.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/lists.py new file mode 100644 index 0000000000000000000000000000000000000000..4cff920c1ebe59ed9d5d8b29129afe32b7949367 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/lists.py @@ -0,0 +1,239 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converter for list operations. + +This includes converting Python lists to TensorArray/TensorList. +""" + +# TODO(mdan): Elaborate the logic here. +# TODO(mdan): Does it even make sense to attempt to try to use TAs? +# The current rule (always convert to TensorArray) is naive and insufficient. +# In general, a better mechanism could look like: +# * convert to TensorList by default +# * leave as Python list if the user explicitly forbids it +# * convert to TensorArray only when complete write once behavior can be +# guaranteed (e.g. list comprehensions) + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.lang import directives +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno + + +class _Statement(object): + + def __init__(self): + self.pop_uses = None + + +class ListTransformer(converter.Base): + """Converts lists and related operations to their TF counterpart.""" + + def visit_List(self, node): + node = self.generic_visit(node) + template = """ + ag__.new_list(elements) + """ + return templates.replace_as_expression(template, elements=node) + + def _replace_append_call(self, node): + assert len(node.args) == 1 + assert isinstance(node.func, gast.Attribute) + template = """ + target = ag__.list_append(target, element) + """ + return templates.replace( + template, + target=node.func.value, + element=node.args[0]) + + def _replace_pop_call(self, node): + # Expressions that use pop() are converted to a statement + expression. + # + # For example: + # + # print(target.pop()) + # + # ... is converted to: + # + # target, target_pop = ag__.list_pop(target) + # print(target_pop) + # + # Here, we just generate the variable name and swap it in, + # and _generate_pop_operation will handle the rest. + # + # Multiple uses of pop() are allowed: + # + # print(tartget.pop(), target.pop()) + # print(tartget.pop().pop()) + # + assert isinstance(node.func, gast.Attribute) + scope = anno.getanno(node, NodeAnno.ARGS_SCOPE) + target_node = node.func.value + + # Attempt to use a related name if one exists. Otherwise use something + # generic. + if anno.hasanno(target_node, anno.Basic.QN): + target_name = anno.getanno(target_node, anno.Basic.QN).ssf() + else: + target_name = 'list_' + pop_var_name = self.ctx.namer.new_symbol(target_name, scope.referenced) + + stmt = self.state[_Statement] + if stmt.pop_uses is None: + stmt.pop_uses = [] + stmt.pop_uses.append((node, pop_var_name)) + + return templates.replace_as_expression('var_name', var_name=pop_var_name) + + def _replace_stack_call(self, node): + assert len(node.args) == 1 + dtype = self.get_definition_directive( + node.args[0], + directives.set_element_type, + 'dtype', + default=templates.replace_as_expression('None')) + template = """ + ag__.list_stack( + target, + opts=ag__.ListStackOpts( + element_dtype=dtype, + original_call=orig_call)) + """ + return templates.replace_as_expression( + template, + dtype=dtype, + target=node.args[0], + orig_call=node.func) + + def visit_Call(self, node): + node = self.generic_visit(node) + + # TODO(mdan): This is insufficient if target is a function argument. + # In the case of function arguments, we need to add the list to the + # function's return value, because it is being modified. + # TODO(mdan): Checking just the name is brittle, can it be improved? + if isinstance(node.func, gast.Attribute): + func_name = node.func.attr + if func_name == 'append' and (len(node.args) == 1): + node = self._replace_append_call(node) + elif func_name == 'pop' and (len(node.args) <= 1): + node = self._replace_pop_call(node) + elif (func_name == 'stack' and (len(node.args) == 1) and + (not node.keywords or node.keywords[0].arg == 'strict')): + # This avoids false positives with keyword args. + # TODO(mdan): handle kwargs properly. + node = self._replace_stack_call(node) + + return node + + def _generate_pop_operation(self, original_call_node, pop_var_name): + assert isinstance(original_call_node.func, gast.Attribute) + + if original_call_node.args: + pop_element = original_call_node.args[0] + else: + pop_element = parser.parse_expression('None') + + # The call will be something like "target.pop()", and the dtype is hooked to + # target, hence the func.value. + # TODO(mdan): For lists of lists, this won't work. + # The reason why it won't work is because it's unclear how to annotate + # the list as a "list of lists with a certain element type" when using + # operations like `l.pop().pop()`. + dtype = self.get_definition_directive( + original_call_node.func.value, + directives.set_element_type, + 'dtype', + default=templates.replace_as_expression('None')) + shape = self.get_definition_directive( + original_call_node.func.value, + directives.set_element_type, + 'shape', + default=templates.replace_as_expression('None')) + + template = """ + target, pop_var_name = ag__.list_pop( + target, element, + opts=ag__.ListPopOpts(element_dtype=dtype, element_shape=shape)) + """ + return templates.replace( + template, + target=original_call_node.func.value, + pop_var_name=pop_var_name, + element=pop_element, + dtype=dtype, + shape=shape) + + def _postprocess_statement(self, node): + """Inserts any separate pop() calls that node may use.""" + pop_uses = self.state[_Statement].pop_uses + if pop_uses: + replacements = [] + for original_call_node, pop_var_name in pop_uses: + replacements.extend( + self._generate_pop_operation(original_call_node, pop_var_name)) + replacements.append(node) + node = replacements + self.state[_Statement].exit() + return node, None + + def _visit_and_process_block(self, block): + return self.visit_block( + block, + before_visit=self.state[_Statement].enter, + after_visit=self._postprocess_statement) + + def visit_FunctionDef(self, node): + node.args = self.generic_visit(node.args) + node.decorator_list = self.visit_block(node.decorator_list) + node.body = self._visit_and_process_block(node.body) + return node + + def visit_For(self, node): + node.target = self.visit(node.target) + node.body = self._visit_and_process_block(node.body) + node.orelse = self._visit_and_process_block(node.orelse) + return node + + def visit_While(self, node): + node.test = self.visit(node.test) + node.body = self._visit_and_process_block(node.body) + node.orelse = self._visit_and_process_block(node.orelse) + return node + + def visit_If(self, node): + node.test = self.visit(node.test) + node.body = self._visit_and_process_block(node.body) + node.orelse = self._visit_and_process_block(node.orelse) + return node + + def visit_With(self, node): + node.items = self.visit_block(node.items) + node.body = self._visit_and_process_block(node.body) + return node + + +def transform(node, ctx): + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + + return ListTransformer(ctx).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/logical_expressions.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/logical_expressions.py new file mode 100644 index 0000000000000000000000000000000000000000..ba99aeaaf7cb5406044b5070b412f03fbc2c280b --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/logical_expressions.py @@ -0,0 +1,131 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converter for logical expressions, e.g. `a and b -> tf.logical_and(a, b)`.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import templates + +# TODO(mdan): Properly extract boolean ops according to lazy eval rules. +# Note that this isn't completely safe either, because tensors may have control +# dependencies. +# Note that for loops that should be done after the loop was converted to +# tf.while_loop so that the expanded conditionals are properly scoped. + +# Used to signal that an operand is safe for non-lazy evaluation. +SAFE_BOOLEAN_OPERAND = 'SAFE_BOOLEAN_OPERAND' + + +LOGICAL_OPERATORS = { + gast.And: 'ag__.and_', + gast.Not: 'ag__.not_', + gast.Or: 'ag__.or_', +} + +EQUALITY_OPERATORS = { + gast.Eq: 'ag__.eq', + gast.NotEq: 'ag__.not_eq', +} + + +class LogicalExpressionTransformer(converter.Base): + """Converts logical expressions to corresponding TF calls.""" + + def _overload_of(self, operator): + op_type = type(operator) + if op_type in LOGICAL_OPERATORS: + return LOGICAL_OPERATORS[op_type] + if self.ctx.user.options.uses(converter.Feature.EQUALITY_OPERATORS): + if op_type in EQUALITY_OPERATORS: + return EQUALITY_OPERATORS[op_type] + return None + + def _as_lambda(self, expr): + return templates.replace_as_expression('lambda: expr', expr=expr) + + def _as_binary_function(self, func_name, arg1, arg2): + return templates.replace_as_expression( + 'func_name(arg1, arg2)', + func_name=parser.parse_expression(func_name), + arg1=arg1, + arg2=arg2) + + def _as_binary_operation(self, op, arg1, arg2): + template = templates.replace_as_expression( + 'arg1 is arg2', # Note: `is` will be replaced with `op` below. + arg1=arg1, + arg2=arg2) + template.ops[0] = op + return template + + def _as_unary_function(self, func_name, arg): + return templates.replace_as_expression( + 'func_name(arg)', func_name=parser.parse_expression(func_name), arg=arg) + + def _process_binop(self, op, left, right): + overload = self._overload_of(op) + if overload is None: + return self._as_binary_operation(op, left, right) + return self._as_binary_function(overload, left, right) + + def visit_Compare(self, node): + node = self.generic_visit(node) + + ops_and_comps = list(zip(node.ops, node.comparators)) + left = node.left + + # Repeated comparisons are converted to conjunctions: + # a < b < c -> a < b and b < c + op_tree = None + while ops_and_comps: + op, right = ops_and_comps.pop(0) + binary_comparison = self._process_binop(op, left, right) + if op_tree is not None: + op_tree = self._as_binary_function('ag__.and_', + self._as_lambda(op_tree), + self._as_lambda(binary_comparison)) + else: + op_tree = binary_comparison + left = right + + assert op_tree is not None + return op_tree + + def visit_UnaryOp(self, node): + node = self.generic_visit(node) + + overload = self._overload_of(node.op) + if overload is None: + return node + + return self._as_unary_function(overload, node.operand) + + def visit_BoolOp(self, node): + node = self.generic_visit(node) + node_values = node.values + right = node.values.pop() + while node_values: + left = node_values.pop() + right = self._as_binary_function( + self._overload_of(node.op), self._as_lambda(left), + self._as_lambda(right)) + return right + + +def transform(node, ctx): + transformer = LogicalExpressionTransformer(ctx) + return transformer.visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/return_statements.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/return_statements.py new file mode 100644 index 0000000000000000000000000000000000000000..fa611f3cc35c75bdcfbb7e829f08a69196f6b7ff --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/return_statements.py @@ -0,0 +1,402 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Canonicalizes functions with multiple returns to use just one.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno + + +BODY_DEFINITELY_RETURNS = 'BODY_DEFINITELY_RETURNS' +ORELSE_DEFINITELY_RETURNS = 'ORELSE_DEFINITELY_RETURNS' +STMT_DEFINITELY_RETURNS = 'STMT_DEFINITELY_RETURNS' + + +class _RewriteBlock(object): + + def __init__(self): + self.definitely_returns = False + + +class ConditionalReturnRewriter(converter.Base): + """Rewrites a pattern where it's unobvious that all paths return a value. + + This rewrite allows avoiding intermediate None return values. + + The following pattern: + + if cond: + + return + else: + + + + is converted to: + + if cond: + + return + else: + + + + and vice-versa (if the else returns, subsequent statements are moved under the + if branch). + """ + + def visit_Return(self, node): + self.state[_RewriteBlock].definitely_returns = True + return node + + def _postprocess_statement(self, node): + # If the node definitely returns (e.g. it's a with statement with a + # return statement in it), then the current block also definitely returns. + if anno.getanno(node, STMT_DEFINITELY_RETURNS, default=False): + self.state[_RewriteBlock].definitely_returns = True + + # The special case: collapse a typical conditional return pattern into + # a single conditional with possibly returns on both branches. This + # reduces the use of None return values, which don't work with TF + # conditionals. + if (isinstance(node, gast.If) + and anno.getanno(node, BODY_DEFINITELY_RETURNS, default=False)): + return node, node.orelse + elif (isinstance(node, gast.If) + and anno.getanno(node, ORELSE_DEFINITELY_RETURNS, default=False)): + return node, node.body + + return node, None + + def _visit_statement_block(self, node, nodes): + self.state[_RewriteBlock].enter() + new_nodes = self.visit_block(nodes, after_visit=self._postprocess_statement) + block_definitely_returns = self.state[_RewriteBlock].definitely_returns + self.state[_RewriteBlock].exit() + return new_nodes, block_definitely_returns + + def visit_While(self, node): + node.test = self.visit(node.test) + node.body, _ = self._visit_statement_block(node, node.body) + node.orelse, _ = self._visit_statement_block(node, node.orelse) + return node + + def visit_For(self, node): + node.iter = self.visit(node.iter) + node.target = self.visit(node.target) + node.body, _ = self._visit_statement_block(node, node.body) + node.orelse, _ = self._visit_statement_block(node, node.orelse) + return node + + def visit_With(self, node): + node.items = self.visit_block(node.items) + node.body, definitely_returns = self._visit_statement_block(node, node.body) + if definitely_returns: + anno.setanno(node, STMT_DEFINITELY_RETURNS, True) + return node + + def visit_Try(self, node): + # We could decide whether a 'try' DEFINITELY_RETURNS based on its components + # It is not clear whether we want to do anything with this given + # a 'try' is likely to throw an exception in some circumstances. + node.body, _ = self._visit_statement_block(node, node.body) + node.orelse, _ = self._visit_statement_block(node, node.orelse) + node.finalbody, _ = self._visit_statement_block(node, node.finalbody) + node.handlers = self.visit_block(node.handlers) + return node + + def visit_ExceptHandler(self, node): + # To determine whether `try` DEFINITELY_RETURNS we need to revisit this. + node.body, _ = self._visit_statement_block(node, node.body) + return node + + def visit_If(self, node): + node.test = self.visit(node.test) + + node.body, body_definitely_returns = self._visit_statement_block( + node, node.body) + if body_definitely_returns: + anno.setanno(node, BODY_DEFINITELY_RETURNS, True) + + node.orelse, orelse_definitely_returns = self._visit_statement_block( + node, node.orelse) + if orelse_definitely_returns: + anno.setanno(node, ORELSE_DEFINITELY_RETURNS, True) + + if body_definitely_returns and orelse_definitely_returns: + self.state[_RewriteBlock].definitely_returns = True + + return node + + def visit_FunctionDef(self, node): + node.args = self.visit(node.args) + node.body, _ = self._visit_statement_block(node, node.body) + return node + + +class _Block(object): + + def __init__(self): + self.is_function = False + self.return_used = False + self.create_guard_next = False + self.create_guard_now = False + + def __repr__(self): + return 'used: {}'.format( + self.return_used) + + +class _Function(object): + + def __init__(self): + self.do_return_var_name = None + self.retval_var_name = None + + def __repr__(self): + return 'return control: {}, return value: {}'.format( + self.do_return_var_name, self.retval_var_name) + + +class ReturnStatementsTransformer(converter.Base): + """Lowers return statements into variables and conditionals. + + Specifically, the following pattern: + + + return val + + + is converted to: + + do_return = False + retval = None + + + + do_return = True + retval = val + + if not do_return: + + + return retval + + The conversion adjusts loops as well: + + + while cond: + + return retval + + is converted to: + + + while not do_return and cond: + + do_return = True + retval = val + """ + + def __init__(self, ctx, allow_missing_return): + super(ReturnStatementsTransformer, self).__init__(ctx) + self.allow_missing_return = allow_missing_return + + def visit_Return(self, node): + for block in reversed(self.state[_Block].stack): + block.return_used = True + block.create_guard_next = True + if block.is_function: + break + + retval = node.value if node.value else parser.parse_expression('None') + + # Note: If `return raises, then the return is aborted. + # The try-catch below ensures the variables remain consistent in that case. + template = """ + try: + do_return_var_name = True + retval_var_name = retval + except: + do_return_var_name = False + raise + """ + node = templates.replace( + template, + do_return_var_name=self.state[_Function].do_return_var_name, + retval_var_name=self.state[_Function].retval_var_name, + retval=retval) + + return node + + def _postprocess_statement(self, node): + if not self.state[_Block].return_used: + return node, None + + state = self.state[_Block] + if state.create_guard_now: + template = """ + if not do_return_var_name: + original_node + """ + cond, = templates.replace( + template, + do_return_var_name=self.state[_Function].do_return_var_name, + original_node=node) + node, block = cond, cond.body + else: + node, block = node, None + + state.create_guard_now = state.create_guard_next + state.create_guard_next = False + + return node, block + + def _visit_statement_block(self, node, nodes): + self.state[_Block].enter() + nodes = self.visit_block(nodes, after_visit=self._postprocess_statement) + self.state[_Block].exit() + return nodes + + def visit_While(self, node): + node.test = self.visit(node.test) + + # Add the check for return to the loop condition. + node.body = self._visit_statement_block(node, node.body) + if self.state[_Block].return_used: + node.test = templates.replace_as_expression( + 'not control_var and test', + test=node.test, + control_var=self.state[_Function].do_return_var_name) + + node.orelse = self._visit_statement_block(node, node.orelse) + return node + + def visit_For(self, node): + node.iter = self.visit(node.iter) + node.target = self.visit(node.target) + + # Add the check for return to the loop condition. + node.body = self._visit_statement_block(node, node.body) + if self.state[_Block].return_used: + extra_test = anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST, default=None) + if extra_test is not None: + extra_test = templates.replace_as_expression( + 'not control_var and extra_test', + extra_test=extra_test, + control_var=self.state[_Function].do_return_var_name) + else: + extra_test = templates.replace_as_expression( + 'not control_var', + control_var=self.state[_Function].do_return_var_name) + anno.setanno(node, anno.Basic.EXTRA_LOOP_TEST, extra_test) + + node.orelse = self._visit_statement_block(node, node.orelse) + return node + + def visit_With(self, node): + node.items = self.visit_block(node.items) + node.body = self._visit_statement_block(node, node.body) + return node + + def visit_Try(self, node): + node.body = self._visit_statement_block(node, node.body) + node.orelse = self._visit_statement_block(node, node.orelse) + node.finalbody = self._visit_statement_block(node, node.finalbody) + node.handlers = self.visit_block(node.handlers) + return node + + def visit_ExceptHandler(self, node): + node.body = self._visit_statement_block(node, node.body) + return node + + def visit_If(self, node): + node.test = self.visit(node.test) + node.body = self._visit_statement_block(node, node.body) + node.orelse = self._visit_statement_block(node, node.orelse) + return node + + def visit_FunctionDef(self, node): + with self.state[_Function] as fn: + with self.state[_Block] as block: + block.is_function = True + + scope = anno.getanno(node, NodeAnno.BODY_SCOPE) + do_return_var_name = self.ctx.namer.new_symbol('do_return', + scope.referenced) + retval_var_name = self.ctx.namer.new_symbol('retval_', scope.referenced) + fn.do_return_var_name = do_return_var_name + fn.retval_var_name = retval_var_name + + node.body = self._visit_statement_block(node, node.body) + + if block.return_used: + + if self.allow_missing_return: + # The function would have a single `with` node that wraps the + # entire body. If the function had a docstring, the body has two + # nodes, with the `with` as the second node. + wrapper_node = node.body[-1] + assert isinstance(wrapper_node, gast.With), ( + 'This transformer requires the functions converter.') + + template = """ + do_return_var_name = False + retval_var_name = ag__.UndefinedReturnValue() + body + return function_context.ret(retval_var_name, do_return_var_name) + """ + + wrapper_node.body = templates.replace( + template, + body=wrapper_node.body, + do_return_var_name=do_return_var_name, + function_context=anno.getanno(node, 'function_context_name'), + retval_var_name=retval_var_name) + else: + template = """ + body + return retval_var_name + """ + node.body = templates.replace( + template, + body=node.body, + do_return_var_name=do_return_var_name, + retval_var_name=retval_var_name) + + return node + + +def transform(node, ctx, default_to_null_return=True): + """Ensure a function has only a single return, at the end.""" + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + + # Note: Technically, these two could be merged into a single walk, but + # keeping them separate helps with readability. + node = ConditionalReturnRewriter(ctx).visit(node) + + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + transformer = ReturnStatementsTransformer( + ctx, allow_missing_return=default_to_null_return) + node = transformer.visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/slices.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/slices.py new file mode 100644 index 0000000000000000000000000000000000000000..f7af271d805315ea677835ad18c026e68a334276 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/slices.py @@ -0,0 +1,83 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converter for slice operations.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.lang import directives +from tensorflow.python.autograph.pyct import templates + + +class SliceTransformer(converter.Base): + """Converts slicing operations to their TF counterpart. + + Currently, relying on the default slice operator that Tensor uses is + insufficient, because TensorArray and tensor lists use dedicated index read + and write functions. + """ + + def _process_single_assignment(self, target, value): + if not isinstance(target, gast.Subscript): + return None + s = target.slice + if isinstance(s, (gast.Tuple, gast.Slice)): + return None + + template = """ + target = ag__.set_item(target, key, item) + """ + return templates.replace( + template, target=target.value, key=target.slice, item=value) + + def visit_Assign(self, node): + node = self.generic_visit(node) + # TODO(mdan): Support unpackings and multiple assignments. + if len(node.targets) != 1: + raise NotImplementedError('multiple assignment') + replacement = self._process_single_assignment(node.targets[0], node.value) + if replacement is not None: + return replacement + return node + + def visit_Subscript(self, node): + node = self.generic_visit(node) + s = node.slice + if isinstance(s, (gast.Tuple, gast.Slice)): + return node + + if not isinstance(node.ctx, gast.Load): + # Index writes are handled at a higher level, one at which the rvalue is + # also available. + return node + + dtype = self.get_definition_directive( + node.value, + directives.set_element_type, + 'dtype', + default=templates.replace_as_expression('None')) + + template = """ + ag__.get_item( + target, + key, + opts=ag__.GetItemOpts(element_dtype=dtype)) + """ + return templates.replace_as_expression( + template, target=node.value, key=s, dtype=dtype) + + +def transform(node, ctx): + return SliceTransformer(ctx).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/variables.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/variables.py new file mode 100644 index 0000000000000000000000000000000000000000..cea96a89f685cc956adba6965a3845c8a03a025c --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/variables.py @@ -0,0 +1,97 @@ +# Copyright 2020 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Overloads all variable read operations.""" + +import gast + +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import templates + + +class VariableAccessTransformer(converter.Base): + """Rewrites basic symbol reads. + + This transformer rewrites variable reads with a "read" operator which allows + tracking activity. + + Example: + + For a basic statement: + + a = b + c + + This is translated to: + + a = ld(b) + ld(c) + + Augmented assignment operations also introduce a `ld` operator: + + a += b + + The assignment target also receives an operator to properly represent the + read: + + a = ld(a) + a += ld(b) + """ + + def visit_Name(self, node): + # Only the loads which existed in the original code are overloaded. + if not anno.hasanno(node, anno.Static.ORIG_DEFINITIONS): + return node + if isinstance(node.ctx, gast.Load): + node = templates.replace_as_expression('ag__.ld(var_)', var_=node) + return node + + def visit_Delete(self, node): + node = self.generic_visit(node) + + rewrite_targets = [] + for tgt in node.targets: + # Don't rewrite composites like `del a[0]`. + if isinstance(tgt, gast.Name): + rewrite_targets.append(tgt) + + if not rewrite_targets: + return node + + results = [] + for tgt in rewrite_targets: + template = """ + var_ = ag__.Undefined(var_name) + """ + results.extend(templates.replace( + template, var_=tgt, var_name=gast.Constant(tgt.id, kind=None))) + remaining_targets = [n for n in node.targets if n not in rewrite_targets] + if remaining_targets: + results.append(gast.Delete(targets=remaining_targets)) + + return results + + def visit_AugAssign(self, node): + if isinstance(node.target, gast.Name): + template = """ + var_ = ag__.ld(var_) + original + """ + node = templates.replace(template, var_=node.target, original=node) + else: + node = self.generic_visit(node) + return node + + +def transform(node, ctx): + return VariableAccessTransformer(ctx).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f742e73e4cccac1c2ebd597151139ec05f95245 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/ag_ctx.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/ag_ctx.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..197a97d6d8c03873319e0bd4d3e5b6863bc32b33 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/ag_ctx.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b636996af2597726edece0aea1e9d1d5deac79d9 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config_lib.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config_lib.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b923a6538a0d86bba5fdf716030c56c1cb86efb7 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config_lib.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12dfdcc977fa6cd527f6c0483d462de518e4f747 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter_testing.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter_testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2244cb66739ab07154d15b50b699b9407ae49c70 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter_testing.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/function_wrappers.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/function_wrappers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1ccbcfb3e7f35b90f3c3dc56988bec380b3a949 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/function_wrappers.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/unsupported_features_checker.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/unsupported_features_checker.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0342377f9f64e5c62232d35401ae50d099b9d94b Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/unsupported_features_checker.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/ag_ctx.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/ag_ctx.py new file mode 100644 index 0000000000000000000000000000000000000000..d174ee5cd616c4ca28f1e183fe5a021b9216d0ef --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/ag_ctx.py @@ -0,0 +1,105 @@ +# Copyright 2019 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Thread-local context managers for AutoGraph.""" + +import enum +import inspect +import threading + +from tensorflow.python.autograph.utils import ag_logging +from tensorflow.python.util.tf_export import tf_export + + +stacks = threading.local() + + +def _control_ctx(): + if not hasattr(stacks, 'control_status'): + stacks.control_status = [_default_control_status_ctx()] + return stacks.control_status + + +@tf_export('__internal__.autograph.control_status_ctx', v1=[]) +def control_status_ctx(): + """Returns the current control context for autograph. + + This method is useful when calling `tf.__internal__.autograph.tf_convert`, + The context will be used by tf_convert to determine whether it should convert + the input function. See the sample usage like below: + + ``` + def foo(func): + return tf.__internal__.autograph.tf_convert( + input_fn, ctx=tf.__internal__.autograph.control_status_ctx())() + ``` + + Returns: + The current control context of autograph. + """ + ret = _control_ctx()[-1] + return ret + + +class Status(enum.Enum): + UNSPECIFIED = 0 + ENABLED = 1 + DISABLED = 2 + + +class ControlStatusCtx(object): + """A context that tracks whether autograph is enabled by the user.""" + + def __init__(self, status, options=None): + self.status = status + self.options = options + + def __enter__(self): + _control_ctx().append(self) + return self + + def __repr__(self): + return '{}[status={}, options={}]'.format( + self.__class__.__name__, self.status, self.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.') diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config.py new file mode 100644 index 0000000000000000000000000000000000000000..eb3bd783136effbbbf0afe884ae434cbffd1583a --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config.py @@ -0,0 +1,62 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Global configuration.""" + +from tensorflow.python.autograph.core import config_lib + +Action = config_lib.Action +Convert = config_lib.Convert +DoNotConvert = config_lib.DoNotConvert + + +# This list is evaluated in order and stops at the first rule that tests True +# for a definitely_convert of definitely_bypass call. +CONVERSION_RULES = ( + # Known packages + Convert('tensorflow.python.training.experimental'), + + # Builtin modules + DoNotConvert('collections'), + DoNotConvert('copy'), + DoNotConvert('cProfile'), + DoNotConvert('inspect'), + DoNotConvert('ipdb'), + DoNotConvert('linecache'), + DoNotConvert('mock'), + DoNotConvert('pathlib'), + DoNotConvert('pdb'), + DoNotConvert('posixpath'), + DoNotConvert('pstats'), + DoNotConvert('re'), + DoNotConvert('threading'), + DoNotConvert('urllib'), + + # Known libraries + DoNotConvert('matplotlib'), + DoNotConvert('numpy'), + DoNotConvert('pandas'), + DoNotConvert('tensorflow'), + DoNotConvert('PIL'), + DoNotConvert('absl.logging'), + + # TODO(b/133417201): Remove. + DoNotConvert('tensorflow_probability'), + + # TODO(b/133842282): Remove. + DoNotConvert('tensorflow_datasets.core'), + + DoNotConvert('keras'), + DoNotConvert('tf_keras'), +) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config_lib.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config_lib.py new file mode 100644 index 0000000000000000000000000000000000000000..9065bf361dc6e3bc0cf791e9e922cc36390c7e82 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config_lib.py @@ -0,0 +1,61 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Global configuration support.""" + +import enum + + +# TODO(mdan): For better performance, allow each rule to take a set names. + + +class Rule(object): + """Base class for conversion rules.""" + + def __init__(self, module_prefix): + self._prefix = module_prefix + + def matches(self, module_name): + return (module_name.startswith(self._prefix + '.') or + module_name == self._prefix) + + +class Action(enum.Enum): + NONE = 0 + CONVERT = 1 + DO_NOT_CONVERT = 2 + + +class DoNotConvert(Rule): + """Indicates that this module should be not converted.""" + + def __str__(self): + return 'DoNotConvert rule for {}'.format(self._prefix) + + def get_action(self, module): + if self.matches(module.__name__): + return Action.DO_NOT_CONVERT + return Action.NONE + + +class Convert(Rule): + """Indicates that this module should be converted.""" + + def __str__(self): + return 'Convert rule for {}'.format(self._prefix) + + def get_action(self, module): + if self.matches(module.__name__): + return Action.CONVERT + return Action.NONE diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter.py new file mode 100644 index 0000000000000000000000000000000000000000..1a8ebeddbc7ccf3bcb9853e7d612d642f1544b41 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter.py @@ -0,0 +1,316 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Converter construction support. + +This module contains a base class for all converters, as well as supporting +structures. These structures are referred to as contexts. + +The class hierarchy is as follows: + + + [extends] converter.Base + [extends] transformer.Base + [extends] gast.nodeTransformer + [uses] transformer.SourceInfo + [uses] converter.EntityContext + [uses] converter.ProgramContext + [uses] transformer.SourceInfo + +converter.Base is a specialization of transformer.Base for AutoGraph. It's a +very lightweight subclass that adds a `ctx` attribute holding the corresponding +EntityContext object (see below). Note that converters are not reusable, and +`visit` will raise an error if called more than once. + +converter.EntityContext contains mutable state associated with an entity that +the converter processes. + +converter.ProgramContext contains mutable state across related entities. For +example, when converting several functions that call one another, the +ProgramContext should be shared across these entities. + +Below is the overall flow at conversion: + + program_ctx = ProgramContext(, , ...) + while : + entity, source_info = + entity_ctx = EntityContext(program_ctx, source_info) + for : + converter = ConverterClass(entity_ctx) + + # May update entity_ctx and program_ctx + entity = converter.visit(entity) + + + +Note that pyct contains a small number of transformers used for static analysis. +These implement transformer.Base, rather than converter.Base, to avoid a +dependency on AutoGraph. +""" + +import enum + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import ast_util +from tensorflow.python.autograph.pyct import parser +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct import transformer +from tensorflow.python.util.tf_export import tf_export + +# TODO(mdan): These contexts can be refactored into first class objects. +# For example, we could define Program and Entity abstractions that hold on +# to the actual entity and have conversion methods. + +# TODO(mdan): Add a test specific to this converter. + + +@tf_export('autograph.experimental.Feature') +class Feature(enum.Enum): + """This enumeration represents optional conversion options. + + These conversion options are experimental. They are subject to change without + notice and offer no guarantees. + + _Example Usage_ + + ```python + optionals= tf.autograph.experimental.Feature.EQUALITY_OPERATORS + @tf.function(experimental_autograph_options=optionals) + def f(i): + if i == 0: # EQUALITY_OPERATORS allows the use of == here. + tf.print('i is zero') + ``` + + Attributes: + ALL: Enable all features. + AUTO_CONTROL_DEPS: Insert of control dependencies in the generated code. + ASSERT_STATEMENTS: Convert Tensor-dependent assert statements to tf.Assert. + BUILTIN_FUNCTIONS: Convert builtin functions applied to Tensors to + their TF counterparts. + EQUALITY_OPERATORS: Whether to convert the equality operator ('==') to + tf.math.equal. + LISTS: Convert list idioms, like initializers, slices, append, etc. + NAME_SCOPES: Insert name scopes that name ops according to context, like the + function they were defined in. + """ + + ALL = 'ALL' + + AUTO_CONTROL_DEPS = 'AUTO_CONTROL_DEPS' + ASSERT_STATEMENTS = 'ASSERT_STATEMENTS' + BUILTIN_FUNCTIONS = 'BUILTIN_FUNCTIONS' + EQUALITY_OPERATORS = 'EQUALITY_OPERATORS' + LISTS = 'LISTS' + NAME_SCOPES = 'NAME_SCOPES' + + @classmethod + def all(cls): + """Returns a tuple that enables all options.""" + return tuple(cls.__members__.values()) + + @classmethod + def all_but(cls, exclude): + """Returns a tuple that enables all but the excluded options.""" + if not isinstance(exclude, (list, tuple, set)): + exclude = (exclude,) + return tuple(set(cls.all()) - set(exclude) - {cls.ALL}) + + +STANDARD_OPTIONS = None # Forward definition. + + +class ConversionOptions(object): + """Immutable container for global conversion flags. + + Attributes: + recursive: bool, whether to recursively convert any user functions or + classes that the converted function may use. + user_requested: bool, whether the conversion was explicitly requested by + the user, as opposed to being performed as a result of other logic. This + value always auto-resets to False in child conversions. + optional_features: Union[Feature, Set[Feature]], controls the use of + optional features in the conversion process. See Feature for available + options. + """ + + def __init__(self, + recursive=False, + user_requested=False, + internal_convert_user_code=True, + optional_features=Feature.ALL): + self.recursive = recursive + self.user_requested = user_requested + # TODO(mdan): Rename to conversion_recursion_depth? + self.internal_convert_user_code = internal_convert_user_code + + if optional_features is None: + optional_features = () + elif isinstance(optional_features, Feature): + optional_features = (optional_features,) + optional_features = frozenset(optional_features) + self.optional_features = optional_features + + def as_tuple(self): + return (self.recursive, self.user_requested, + self.internal_convert_user_code, self.optional_features) + + def __hash__(self): + return hash(self.as_tuple()) + + def __eq__(self, other): + assert isinstance(other, ConversionOptions) + return self.as_tuple() == other.as_tuple() + + def __str__(self): + return 'ConversionOptions[{}]' + + def uses(self, feature): + return (Feature.ALL in self.optional_features or + feature in self.optional_features) + + def call_options(self): + """Returns the corresponding options to be used for recursive conversion.""" + return ConversionOptions( + recursive=self.recursive, + user_requested=False, + internal_convert_user_code=self.recursive, + optional_features=self.optional_features) + + def to_ast(self): + """Returns a representation of this object as an AST node. + + The AST node encodes a constructor that would create an object with the + same contents. + + Returns: + ast.Node + """ + if self == STANDARD_OPTIONS: + return parser.parse_expression('ag__.STD') + + template = """ + ag__.ConversionOptions( + recursive=recursive_val, + user_requested=user_requested_val, + optional_features=optional_features_val, + internal_convert_user_code=internal_convert_user_code_val) + """ + + def list_of_features(values): + return parser.parse_expression('({})'.format(', '.join( + 'ag__.{}'.format(str(v)) for v in values))) + + expr_ast = templates.replace( + template, + recursive_val=parser.parse_expression(str(self.recursive)), + user_requested_val=parser.parse_expression(str(self.user_requested)), + internal_convert_user_code_val=parser.parse_expression( + str(self.internal_convert_user_code)), + optional_features_val=list_of_features(self.optional_features)) + return expr_ast[0].value + + +STANDARD_OPTIONS = ConversionOptions( + recursive=True, + user_requested=False, + internal_convert_user_code=True, + optional_features=None) + + +class ProgramContext(object): + """ProgramContext keeps track of converting function hierarchies. + + Attributes: + options: ConversionOptions + autograph_module: Deprecated. Do not use. + """ + + def __init__(self, options, autograph_module=None): + self.options = options + self.autograph_module = autograph_module + + +class Base(transformer.Base): + """All converters should inherit from this class. + + Attributes: + ctx: EntityContext + """ + + def __init__(self, ctx): + super(Base, self).__init__(ctx) + + self._used = False + self._ast_depth = 0 + + def get_definition_directive(self, node, directive, arg, default): + """Returns the unique directive argument for a symbol. + + See lang/directives.py for details on directives. + + Example: + # Given a directive in the code: + ag.foo_directive(bar, baz=1) + + # One can write for an AST node Name(id='bar'): + get_definition_directive(node, ag.foo_directive, 'baz') + + Args: + node: ast.AST, the node representing the symbol for which the directive + argument is needed. + directive: Callable[..., Any], the directive to search. + arg: str, the directive argument to return. + default: Any + + Raises: + ValueError: if conflicting annotations have been found + """ + defs = anno.getanno(node, anno.Static.ORIG_DEFINITIONS, ()) + if not defs: + return default + + arg_values_found = [] + for def_ in defs: + if (directive in def_.directives and arg in def_.directives[directive]): + arg_values_found.append(def_.directives[directive][arg]) + + if not arg_values_found: + return default + + if len(arg_values_found) == 1: + return arg_values_found[0] + + # If multiple annotations reach the symbol, they must all match. If they do, + # return any of them. + first_value = arg_values_found[0] + for other_value in arg_values_found[1:]: + if not ast_util.matches(first_value, other_value): + qn = anno.getanno(node, anno.Basic.QN) + raise ValueError( + '%s has ambiguous annotations for %s(%s): %s, %s' % + (qn, directive.__name__, arg, parser.unparse(other_value).strip(), + parser.unparse(first_value).strip())) + return first_value + + def visit(self, node): + if not self._ast_depth: + if self._used: + raise ValueError('converter objects cannot be reused') + self._used = True + + self._ast_depth += 1 + try: + return super(Base, self).visit(node) + finally: + self._ast_depth -= 1 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter_testing.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter_testing.py new file mode 100644 index 0000000000000000000000000000000000000000..a3ac5cbc20e219a47889083baf28cac7e73c1ba1 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter_testing.py @@ -0,0 +1,126 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Base class for tests in this module.""" + +import contextlib +import inspect +import io +import sys +import types + +from tensorflow.python.autograph.core import config +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.impl import api +from tensorflow.python.framework import ops +from tensorflow.python.platform import test + + +def allowlist(f): + """Helper that marks a callable as whtelitisted.""" + if 'allowlisted_module_for_testing' not in sys.modules: + allowlisted_mod = types.ModuleType('allowlisted_module_for_testing') + sys.modules['allowlisted_module_for_testing'] = allowlisted_mod + config.CONVERSION_RULES = ( + (config.DoNotConvert('allowlisted_module_for_testing'),) + + config.CONVERSION_RULES) + + f.__module__ = 'allowlisted_module_for_testing' + + +def is_inside_generated_code(): + """Tests whether the caller is generated code. Implementation-specific.""" + frame = inspect.currentframe() + try: + frame = frame.f_back + + internal_stack_functions = ('converted_call', '_call_unconverted') + # Walk up the stack until we're out of the internal functions. + while (frame is not None and + frame.f_code.co_name in internal_stack_functions): + frame = frame.f_back + if frame is None: + return False + + return 'ag__' in frame.f_locals + finally: + del frame + + +class TestingTranspiler(api.PyToTF): + """Testing version that only applies given transformations.""" + + def __init__(self, converters, ag_overrides): + super(TestingTranspiler, self).__init__() + if isinstance(converters, (list, tuple)): + self._converters = converters + else: + self._converters = (converters,) + self.transformed_ast = None + self._ag_overrides = ag_overrides + + def get_extra_locals(self): + retval = super(TestingTranspiler, self).get_extra_locals() + if self._ag_overrides: + modified_ag = types.ModuleType('fake_autograph') + modified_ag.__dict__.update(retval['ag__'].__dict__) + modified_ag.__dict__.update(self._ag_overrides) + retval['ag__'] = modified_ag + return retval + + def transform_ast(self, node, ctx): + node = self.initial_analysis(node, ctx) + + for c in self._converters: + node = c.transform(node, ctx) + + self.transformed_ast = node + self.transform_ctx = ctx + return node + + +class TestCase(test.TestCase): + """Base class for unit tests in this module. Contains relevant utilities.""" + + def setUp(self): + # AutoGraph tests must run in graph mode to properly test control flow. + self.graph = ops.Graph().as_default() + self.graph.__enter__() + + def tearDown(self): + self.graph.__exit__(None, None, None) + + @contextlib.contextmanager + def assertPrints(self, expected_result): + try: + out_capturer = io.StringIO() + sys.stdout = out_capturer + yield + self.assertEqual(out_capturer.getvalue(), expected_result) + finally: + sys.stdout = sys.__stdout__ + + def transform( + self, f, converter_module, include_ast=False, ag_overrides=None): + program_ctx = converter.ProgramContext( + options=converter.ConversionOptions(recursive=True), + autograph_module=api) + + tr = TestingTranspiler(converter_module, ag_overrides) + transformed, _, _ = tr.transform_function(f, program_ctx) + + if include_ast: + return transformed, tr.transformed_ast, tr.transform_ctx + + return transformed diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/function_wrappers.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/function_wrappers.py new file mode 100644 index 0000000000000000000000000000000000000000..0e1f1da2c0f3c5d1cb34251ecc63bde1b536274a --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/function_wrappers.py @@ -0,0 +1,113 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Support for wrapping converted functions bodies with auxiliary logic.""" + +from tensorflow.python.autograph.core import ag_ctx +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.operators import variables +from tensorflow.python.framework import auto_control_deps +from tensorflow.python.framework import ops +from tensorflow.python.framework import tensor_util +from tensorflow.python.util import nest + + +# TODO(mdan): Move this into operators - it represents a function definition. + + +class FunctionScope(object): + """Context manager that wraps the body of a converted function. + + This context manager handles various operations related to the scope of a + function: + * optional TF name scopes - these name scopes match the name of the + function, for easy visualization in tensorBoard; + * optional automatic control dependencies - this adds the same mechanism + for control dependencies that is used by `@tf.function`; it can be + optionally enabled when using `tf.autograph.to_graph`; + * tracking of autograph conversion state (whether it's enabled by the user, + conversion options; + """ + + def __init__(self, function_name, scope_name, options): + self.name = scope_name + self.options = options + + if options.user_requested: + self.autograph_ctx = ag_ctx.ControlStatusCtx(ag_ctx.Status.ENABLED, + options) + self.callopts = options.call_options() + + use_name_scope = options.uses(converter.Feature.NAME_SCOPES) + self.use_name_scope = use_name_scope + if use_name_scope: + self.name_scope = ops.name_scope(self._sanitize(function_name)) + + use_auto_deps = self.options.uses(converter.Feature.AUTO_CONTROL_DEPS) + self.use_auto_deps = use_auto_deps + if use_auto_deps: + self.autodeps_scope = auto_control_deps.AutomaticControlDependencies() + self._return_value_marked = False + + def _sanitize(self, name): + """See https://www.tensorflow.org/api_docs/python/tf/Graph#name_scope.""" + # TensorFlow doesn't like leading underscores at the top level. + if name and name.startswith('_'): + name = 'fn' + name + return name + + def __enter__(self): + if self.options.user_requested: + self.autograph_ctx.__enter__() + if self.use_name_scope: + self.name_scope.__enter__() + if self.use_auto_deps: + self.autodeps_scope.__enter__() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + if self.options.user_requested: + self.autograph_ctx.__exit__(exc_type, exc_val, exc_tb) + if self.use_name_scope: + self.name_scope.__exit__(exc_type, exc_val, exc_tb) + if self.use_auto_deps: + self.autodeps_scope.__exit__(exc_type, exc_val, exc_tb) + + def ret(self, value, did_return): + """Marks a value as returned from the function guarded by the scope.""" + del did_return + + if isinstance(value, variables.UndefinedReturnValue): + return None + + if self.use_auto_deps: + self._return_value_marked = True + if value is None: + # We don't create dummy returns, to preserve Python semantics. The user + # is responsible for adding a return value to the top-level function. + return None + + def _mark_return_if_tensor(t): + if tensor_util.is_tf_type(t): + return self.autodeps_scope.mark_as_return(t) + return t + + value = nest.map_structure(_mark_return_if_tensor, value) + return value + + +def with_function_scope(thunk, scope_name, options): + """Inline version of the FunctionScope context manager.""" + with FunctionScope('lambda_', scope_name, options) as scope: + return thunk(scope) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/unsupported_features_checker.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/unsupported_features_checker.py new file mode 100644 index 0000000000000000000000000000000000000000..7fad7eb728c255033e75957ba71a95f568d0747d --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/unsupported_features_checker.py @@ -0,0 +1,57 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Checkers for detecting unsupported Python features.""" + +import gast + +from tensorflow.python.autograph.pyct import errors + + +class UnsupportedFeaturesChecker(gast.NodeVisitor): + """Quick check for Python features we know we don't support. + + Any features detected will cause AutoGraph to not compile a function. + """ + + def visit_Attribute(self, node): + if (node.attr is not None + and node.attr.startswith('__') and not node.attr.endswith('__')): + raise errors.UnsupportedLanguageElementError( + 'mangled names are not yet supported') + self.generic_visit(node) + + def visit_For(self, node): + if node.orelse: + raise errors.UnsupportedLanguageElementError( + 'for/else statement not yet supported') + self.generic_visit(node) + + def visit_While(self, node): + if node.orelse: + raise errors.UnsupportedLanguageElementError( + 'while/else statement not yet supported') + self.generic_visit(node) + + # These checks could potentially be replaced with inspect.isgeneratorfunction + # to avoid a getsource/parse/ast-walk round trip. + def visit_Yield(self, node): + raise errors.UnsupportedLanguageElementError('generators are not supported') + + def visit_YieldFrom(self, node): + raise errors.UnsupportedLanguageElementError('generators are not supported') + + +def verify(node): + UnsupportedFeaturesChecker().visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c9b54cbd453cdbc16252b00aaa410f1c71efaaa Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/api.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/api.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0e6bd126f977fb6948bf506d2798209347403fa Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/api.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/conversion.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/conversion.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef157783b338497b28440493c4f98e2edb4ad465 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/conversion.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/api.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/api.py new file mode 100644 index 0000000000000000000000000000000000000000..b60c457599e71726fa984a6bbf4e5d62b0fe2d8f --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/api.py @@ -0,0 +1,949 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""This module contains the user- and codegen-facing API for AutoGraph.""" + +import functools +import importlib +import inspect +import os +import sys +import textwrap +import traceback + +from tensorflow.python.autograph import operators +from tensorflow.python.autograph import utils +from tensorflow.python.autograph.converters import asserts +from tensorflow.python.autograph.converters import break_statements +from tensorflow.python.autograph.converters import call_trees +from tensorflow.python.autograph.converters import conditional_expressions +from tensorflow.python.autograph.converters import continue_statements +from tensorflow.python.autograph.converters import control_flow +from tensorflow.python.autograph.converters import directives +from tensorflow.python.autograph.converters import functions +from tensorflow.python.autograph.converters import lists +from tensorflow.python.autograph.converters import logical_expressions +from tensorflow.python.autograph.converters import return_statements +from tensorflow.python.autograph.converters import slices +from tensorflow.python.autograph.converters import variables +from tensorflow.python.autograph.core import ag_ctx +from tensorflow.python.autograph.core import converter +from tensorflow.python.autograph.core import function_wrappers +from tensorflow.python.autograph.core import unsupported_features_checker +from tensorflow.python.autograph.impl import conversion +from tensorflow.python.autograph.lang import special_functions +from tensorflow.python.autograph.operators import py_builtins +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import error_utils +from tensorflow.python.autograph.pyct import errors +from tensorflow.python.autograph.pyct import inspect_utils +from tensorflow.python.autograph.pyct import origin_info +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import transpiler +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis import reaching_definitions +from tensorflow.python.autograph.utils import ag_logging as logging +from tensorflow.python.eager.polymorphic_function import tf_method_target +from tensorflow.python.framework import errors_impl +from tensorflow.python.util import tf_decorator +from tensorflow.python.util import tf_inspect +from tensorflow.python.util import tf_stack +from tensorflow.python.util.tf_export import tf_export + + +def is_autograph_strict_conversion_mode(): + return int(os.environ.get('AUTOGRAPH_STRICT_CONVERSION', '0')) > 0 + + +# +# Error handling +# + + +# TODO(mdan): Export this symbol. +class AutoGraphError(errors.PyCTError): + """Base class for all AutoGraph exceptions.""" + pass + + +class ConversionError(AutoGraphError): + """Raised during the conversion process.""" + pass + + +class StagingError(AutoGraphError): + """Raised during the staging (i.e. Python execution) of converted code.""" + pass + + +class _ErrorMetadata(error_utils.ErrorMetadataBase): + """AutoGraph-specific error metadata. See base class.""" + + def create_exception(self, source_error): + preferred_type = type(source_error) + if issubclass(preferred_type, errors_impl.OpError): + # Best-effort unpacking of OpError exceptions. + # TODO(mdan): Use a mechanism that is more future-proof. + init_argspec = tf_inspect.getfullargspec(preferred_type.__init__) + message = self.get_message() + init_args = tuple(init_argspec.args) + # At the time of this writing, TF errors either take 3 or 4 arguments, + # the argument '*args' may or may not be used. + if init_args == ('self', 'node_def', 'op', 'message'): + return preferred_type(source_error.node_def, source_error.op, message, + source_error.experimental_payloads) + + elif preferred_type in (errors.PyCTError, AutoGraphError, ConversionError, + StagingError, errors_impl.InaccessibleTensorError, + errors_impl.OperatorNotAllowedInGraphError): + return preferred_type(self.get_message()) + + exc = super(_ErrorMetadata, self).create_exception(source_error) + if exc is not None: + return exc + + # Note: While changing an error's message property to change the message it + # displays will probably work a lot of times, there is no standard way in + # Python to do that. The safest way is therefore to create a new exception. + # For user defined exceptions, we could define an interface that allowed + # them to work under this mechanism. + return StagingError(self.get_message()) + + +def _attach_error_metadata(e, f): + """Augments an error with the metadata necessary for rewrite.""" + if hasattr(e, 'ag_pass_through'): + return + + metadata = getattr(e, 'ag_error_metadata', None) + source_map = f.ag_source_map + + if metadata is None: + logging.log(1, 'Caught error in user callable %s', f, exc_info=True) + message = '{}: {}'.format(e.__class__.__name__, e) + else: + message = None + + cause_tb = traceback.extract_tb(sys.exc_info()[2])[1:] + + e.ag_error_metadata = _ErrorMetadata(cause_tb, metadata, message, source_map, + __file__) + + +class StackTraceMapper(tf_stack.StackTraceMapper): + """Remaps generated code to code it originated from.""" + + def __init__(self, converted_fn): + super().__init__() + self._source_map = converted_fn.ag_source_map + # This may be called repeatedly: once on entry, by the superclass, then by + # each child context manager. + self._cached_map = None + + def get_effective_source_map(self): + if self._cached_map is not None: + return self._cached_map + + parent_map = self.parent.get_effective_source_map() + + effective_source_map = {} + for loc, origin in self._source_map.items(): + effective_source_map[(loc.filename, loc.lineno)] = (origin.loc.filename, + origin.loc.lineno, + origin.function_name) + + for key, value in parent_map.items(): + filename, lineno, _ = value + value_loc = origin_info.LineLocation(filename=filename, lineno=lineno) + if value_loc in self._source_map: + origin = self._source_map[value_loc] + effective_source_map[key] = (origin.loc.filename, origin.loc.lineno, + origin.function_name) + else: + effective_source_map[key] = value + + self._cached_map = effective_source_map + return effective_source_map + + +# +# Actual source code transformation +# + + +class PyToTF(transpiler.PyToPy): + """The TensorFlow AutoGraph transformer.""" + + def __init__(self): + super(PyToTF, self).__init__() + self._extra_locals = None + + def get_transformed_name(self, node): + return 'tf__' + super(PyToTF, self).get_transformed_name(node) + + def get_extra_locals(self): + if self._extra_locals is None: + # TODO(mdan): Move into core or replace with an actual importable module. + # Craft a module that exposes the external API as well as certain + # internal modules. + module_spec = importlib.machinery.ModuleSpec('autograph', None) + ag_internal = importlib.util.module_from_spec(module_spec) + ag_internal.__dict__.update(inspect.getmodule(PyToTF).__dict__) + ag_internal.ConversionOptions = converter.ConversionOptions + ag_internal.STD = converter.STANDARD_OPTIONS + ag_internal.Feature = converter.Feature + ag_internal.utils = utils + ag_internal.FunctionScope = function_wrappers.FunctionScope + ag_internal.with_function_scope = function_wrappers.with_function_scope + # TODO(mdan): Add safeguards against name clashes. + # We don't want to create a submodule because we want the operators to be + # accessible as ag__. + ag_internal.__dict__.update(special_functions.__dict__) + ag_internal.__dict__.update(operators.__dict__) + + self._extra_locals = {'ag__': ag_internal} + return self._extra_locals + + def get_caching_key(self, ctx): + return ctx.options + + def initial_analysis(self, node, ctx): + graphs = cfg.build(node) + node = qual_names.resolve(node) + node = activity.resolve(node, ctx, None) + node = reaching_definitions.resolve(node, ctx, graphs) + anno.dup( + node, + { + anno.Static.DEFINITIONS: anno.Static.ORIG_DEFINITIONS, + }, + ) + return node + + def transform_ast(self, node, ctx): + unsupported_features_checker.verify(node) + node = self.initial_analysis(node, ctx) + + node = functions.transform(node, ctx) + node = directives.transform(node, ctx) + node = break_statements.transform(node, ctx) + if ctx.user.options.uses(converter.Feature.ASSERT_STATEMENTS): + node = asserts.transform(node, ctx) + # Note: sequencing continue canonicalization before for loop one avoids + # dealing with the extra loop increment operation that the for + # canonicalization creates. + node = continue_statements.transform(node, ctx) + node = return_statements.transform(node, ctx) + if ctx.user.options.uses(converter.Feature.LISTS): + node = lists.transform(node, ctx) + node = slices.transform(node, ctx) + node = call_trees.transform(node, ctx) + node = control_flow.transform(node, ctx) + node = conditional_expressions.transform(node, ctx) + node = logical_expressions.transform(node, ctx) + node = variables.transform(node, ctx) + return node + + +def _convert_actual(entity, program_ctx): + """Applies AutoGraph to entity.""" + + # TODO(mdan): Put these extra fields inside __autograph_info__. + if not hasattr(entity, '__code__'): + raise ValueError('Cannot apply autograph to a function that doesn\'t ' + 'expose a __code__ object. If this is a @tf.function,' + ' try passing f.python_function instead.') + + transformed, module, source_map = _TRANSPILER.transform(entity, program_ctx) + + assert not hasattr(transformed, 'ag_module') + assert not hasattr(transformed, 'ag_source_map') + transformed.ag_module = module + transformed.ag_source_map = source_map + return transformed + + +# +# Generated code support +# + + +def autograph_artifact(entity, extras=None): + if inspect.ismethod(entity): + setattr(entity.__func__, 'autograph_info__', extras) + else: + setattr(entity, 'autograph_info__', extras) + return entity + + +def is_autograph_artifact(entity): + return hasattr(entity, 'autograph_info__') + + +def converted_call(f, args, kwargs, caller_fn_scope=None, options=None): + """Converts a function call inline. + + For internal use only. + + Note: The argument list is optimized for readability of generated code, which + may look like this: + + ag__.converted_call(f, (arg1, arg2), None, fscope) + ag__.converted_call(f, (), dict(arg1=val1, **kwargs), fscope) + ag__.converted_call(f, (arg1, arg2) + varargs, dict(**kwargs), lscope) + + Args: + f: The function to convert. + args: Tuple, the original positional arguments of f + kwargs: Optional[Dict], the original keyword arguments of f + caller_fn_scope: Optional[function_wrappers.FunctionScope], the function + scope of the converted function in which this call was originally made. + options: Optional[converter.ConversionOptions], conversion options. If not + specified, the value of caller_fn_scope.callopts is used. Either options + or caller_fn_scope must be present. + + Returns: + Any, the result of executing a possibly-converted `f` with the given + arguments. + """ + logging.log(1, 'Converted call: %s\n args: %s\n kwargs: %s\n', f, args, + kwargs) + + if options is None: + if caller_fn_scope is None: + raise ValueError('either caller_fn_scope or options must have a value') + options = caller_fn_scope.callopts + + if conversion.is_in_allowlist_cache(f, options): + logging.log(2, 'Allowlisted %s: from cache', f) + return _call_unconverted(f, args, kwargs, options, False) + + if ag_ctx.control_status_ctx().status == ag_ctx.Status.DISABLED: + logging.log(2, 'Allowlisted: %s: AutoGraph is disabled in context', f) + return _call_unconverted(f, args, kwargs, options, False) + + if is_autograph_artifact(f): + logging.log(2, 'Permanently allowed: %s: AutoGraph artifact', f) + return _call_unconverted(f, args, kwargs, options) + + # If this is a partial, unwrap it and redo all the checks. + if isinstance(f, functools.partial): + new_kwargs = {} + if f.keywords is not None: + # Use copy to avoid mutating the underlying keywords. + new_kwargs = f.keywords.copy() + if kwargs is not None: + new_kwargs.update(kwargs) + new_args = f.args + args + logging.log(3, 'Forwarding call of partial %s with\n%s\n%s\n', f, new_args, + new_kwargs) + return converted_call( + f.func, + new_args, + new_kwargs, + caller_fn_scope=caller_fn_scope, + options=options) + + if inspect_utils.isbuiltin(f): + if f is eval: + return py_builtins.eval_in_original_context(f, args, caller_fn_scope) + if f is super: + return py_builtins.super_in_original_context(f, args, caller_fn_scope) + if f is globals: + return py_builtins.globals_in_original_context(caller_fn_scope) + if f is locals: + return py_builtins.locals_in_original_context(caller_fn_scope) + if kwargs: + return py_builtins.overload_of(f)(*args, **kwargs) + else: + return py_builtins.overload_of(f)(*args) + + if conversion.is_unsupported(f): + return _call_unconverted(f, args, kwargs, options) + + if not options.user_requested and conversion.is_allowlisted(f): + return _call_unconverted(f, args, kwargs, options) + + # internal_convert_user_code is for example turned off when issuing a dynamic + # call conversion from generated code while in nonrecursive mode. In that + # case we evidently don't want to recurse, but we still have to convert + # things like builtins. + if not options.internal_convert_user_code: + return _call_unconverted(f, args, kwargs, options) + + try: + if inspect.ismethod(f) or inspect.isfunction(f): + target_entity = f + effective_args = args + + f_self = getattr(f, '__self__', None) + if f_self is not None: + if isinstance(f_self, tf_method_target.TfMethodTarget): + f_self = f_self.target + effective_args = (f_self,) + effective_args + + elif hasattr(f, '__class__') and hasattr(f.__class__, '__call__'): + # Callable objects. Dunder methods have special lookup rules, see: + # https://docs.python.org/3/reference/datamodel.html#specialnames + # TODO(mdan): Recurse into converted_call to simplify other verifications. + # This should be handled in the same way as partials. + target_entity = f.__class__.__call__ + effective_args = (f,) + args + + else: + target_entity = f + raise NotImplementedError('unknown callable type "%s"' % type(f)) + + except Exception as e: # pylint:disable=broad-except + logging.log(1, 'Error transforming entity %s', target_entity, exc_info=True) + if is_autograph_strict_conversion_mode(): + raise + return _fall_back_unconverted(f, args, kwargs, options, e) + + if not hasattr(target_entity, '__code__'): + logging.log(2, 'Permanently allowed: %s: native binding', target_entity) + return _call_unconverted(f, args, kwargs, options) + elif (hasattr(target_entity.__code__, 'co_filename') and + target_entity.__code__.co_filename == ''): + # TODO(mdan): __globals__['txt'] might work in Py3. + logging.log(2, 'Permanently allowed: %s: dynamic code (exec?)', + target_entity) + return _call_unconverted(f, args, kwargs, options) + + try: + program_ctx = converter.ProgramContext(options=options) + converted_f = _convert_actual(target_entity, program_ctx) + if logging.has_verbosity(2): + _log_callargs(converted_f, effective_args, kwargs) + except Exception as e: # pylint:disable=broad-except + logging.log(1, 'Error transforming entity %s', target_entity, exc_info=True) + if is_autograph_strict_conversion_mode(): + raise + return _fall_back_unconverted(f, args, kwargs, options, e) + + with StackTraceMapper(converted_f), tf_stack.CurrentModuleFilter(): + try: + if kwargs is not None: + result = converted_f(*effective_args, **kwargs) + else: + result = converted_f(*effective_args) + except Exception as e: + _attach_error_metadata(e, converted_f) + raise + + return result + + +def _call_unconverted(f, args, kwargs, options, update_cache=True): + """Calls the original function without converting with AutoGraph.""" + if update_cache: + conversion.cache_allowlisted(f, options) + + if (inspect.ismethod(f) and + isinstance(f.__self__, tf_method_target.TfMethodTarget)): + return f.__self__.call(args, kwargs) + + if kwargs is not None: + return f(*args, **kwargs) + return f(*args) + + +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) + + +# +# TensorFlow integration +# + + +@tf_export('__internal__.autograph.tf_convert', v1=[]) +def tf_convert(f, ctx, convert_by_default=True, user_requested=False): + """Decorator that applies AutoGraph to a function. + + Use in internal APIs. + + This API is suitable for high order functions internal to the TensorFlow API, + and more generally any function to which AutoGraph is not applied. + + Guidance: `convert` was a decorator meant for use directly by developers, but + most of today's uses go through `tf.function`. `tf_convert` is to be called + from high order functions internal to TF. By default, all the internal + TensorFlow functions are skipped when AutoGraph processes the code. This may + lead to user-supplied functions to be incorrectly skipped as well. + `tf_convert` helps avoid that. See the following example for more details. + + ``` + =====tf_internal_module.py===== + + def unconverted(input_fn): + return input_fn() + + def converted(input_fn): + return tf.__internal__.autograph.tf_convert( + input_fn, ctx=tf.__internal__.autograph.control_status_ctx())() + + ======user_module.py====== + + @tf.function + def foo(input_fn) + return unconverted(input_fn) + + @tf.function + def bar(input_fn) + return converted(input_fn) + + @tf.function(autograph=False) + def baz(input_fn) + return converted(input_fn) + ``` + + The `foo` method above will execute the `input_fn` without autograph + conversion, while the `bar` method will run an autographed `input_fn`. The + `baz` method will run an unconverted `input_fn`, since `tf_convert` respect + the control status context. + + Note that both methods in `tf_internal_module` are skipped by autograph when + tracing the `tf.function`. The configuration of whether a module/package + should be skipped by autograph is controlled in + tensorflow/python/autograph/core/config.py. + + Args: + f: Callable. + ctx: ag_ctx.ControlStatusCtx, the Autograph context in which `f` is used. + convert_by_default: bool, whether to use AutoGraph when the context doesn't + specify. + user_requested: bool, whether to ignore the conversion allowlist. See + ConversionOptions.user_requested. + + Returns: + Either `f or the converted version of `f`. + """ + + if is_autograph_artifact(f): + return f + f_wrapper = f + decorators, f = tf_decorator.unwrap(f) + + # TODO(mdan): Grab features from context. + # Note: we pass the original context through to convert to properly handle the + # following scenario, which can be used inside TF implementations: + # + # ctx = ag_ctx.control_status_ctx() + # @function(autograph=False) # Low-level graph code + # def inner_fn(): + # # The context is disabled here, but should be enabled in user user_fn + # tf_convert(user_fn, ctx=ctx) + if ctx.status == ag_ctx.Status.ENABLED: + wrapper_factory = convert( + recursive=True, user_requested=user_requested, conversion_ctx=ctx) + elif ctx.status == ag_ctx.Status.DISABLED: + wrapper_factory = do_not_convert + elif ctx.status == ag_ctx.Status.UNSPECIFIED: + if convert_by_default: + wrapper_factory = convert( + recursive=True, user_requested=user_requested, conversion_ctx=ctx) + else: + wrapper_factory = call_with_unspecified_conversion_status + else: + assert False, 'This switch contains all possible cases!' + wrapper = wrapper_factory(f) + + if decorators: + wrapper = tf_decorator.rewrap(f_wrapper, f, wrapper) + + return autograph_artifact(wrapper) + + +def call_with_unspecified_conversion_status(func): + """Decorator that resets the conversion context to the unspecified status.""" + + def wrapper(*args, **kwargs): + with ag_ctx.ControlStatusCtx(status=ag_ctx.Status.UNSPECIFIED): + return func(*args, **kwargs) + + if inspect.isfunction(func) or inspect.ismethod(func): + wrapper = functools.update_wrapper(wrapper, func) + + return autograph_artifact(wrapper) + + +def _log_callargs(f, args, kwargs): + """Logging helper.""" + logging.log(2, 'Defaults of %s : %s', f, f.__defaults__) + logging.log(2, 'KW defaults of %s : %s', f, f.__kwdefaults__) + + if kwargs is not None: + callargs = tf_inspect.getcallargs(f, *args, **kwargs) + else: + callargs = tf_inspect.getcallargs(f, *args) + + formatted_callargs = '\n'.join( + ' {}: {}'.format(k, v) for k, v in callargs.items()) + logging.log(2, 'Calling %s with\n%s\n', f, formatted_callargs) + + +# +# Public API +# + + +@tf_export('autograph.experimental.do_not_convert') +def do_not_convert(func=None): + """Decorator that suppresses the conversion of a function. + + Args: + func: function to decorate. + + Returns: + If `func` is not None, returns a `Callable` which is equivalent to + `func`, but is not converted by AutoGraph. + If `func` is None, returns a decorator that, when invoked with a + single `func` argument, returns a `Callable` equivalent to the + above case. + """ + if func is None: + return do_not_convert + + def wrapper(*args, **kwargs): + with ag_ctx.ControlStatusCtx(status=ag_ctx.Status.DISABLED): + return func(*args, **kwargs) + + if inspect.isfunction(func) or inspect.ismethod(func): + wrapper = functools.update_wrapper(wrapper, func) + + return autograph_artifact(wrapper) + + +# TODO(mdan): Make private. +def convert(recursive=False, + optional_features=None, + user_requested=True, + conversion_ctx=ag_ctx.NullCtx()): + """Decorator that compiles a function to use TensorFlow ops. + + The decorator is dynamic - it recompiles the target whenever the decorated + function is called. This means the parameter values are known at conversion. + It also means that repeated calls with different types of parameters will be + correctly processed. + + Args: + recursive: bool, whether to recursively convert any functions or classes + that the converted function may use. + optional_features: converted.Feature, allows toggling optional or + experimental features. When set to None, only the core features are + enabled. + user_requested: bool, whether this is a function that the user explicitly + asked to be converted. See ConversionOptions.user_requested. + conversion_ctx: Optional ag_ctx.ControlStatusCtx, the Autograph context in + which `f` is used. + + Returns: + Callable, a decorator that converts the given function into an equivalent + function that uses TensorFlow ops. + """ + + def decorator(f): + """Decorator implementation.""" + + def wrapper(*args, **kwargs): + """Wrapper that calls the converted version of f.""" + options = converter.ConversionOptions( + recursive=recursive, + user_requested=user_requested, + optional_features=optional_features) + try: + with conversion_ctx: + return converted_call(f, args, kwargs, options=options) + except Exception as e: # pylint:disable=broad-except + if hasattr(e, 'ag_error_metadata'): + raise e.ag_error_metadata.to_exception(e) + else: + raise + + if inspect.isfunction(f) or inspect.ismethod(f): + wrapper = functools.update_wrapper(wrapper, f) + + decorated_wrapper = tf_decorator.make_decorator(f, wrapper) + return autograph_artifact(decorated_wrapper) + + return decorator + + +# pylint:disable=line-too-long +@tf_export('autograph.to_graph', v1=[]) +def to_graph(entity, recursive=True, experimental_optional_features=None): + """Converts a Python entity into a TensorFlow graph. + + Also see: `tf.autograph.to_code`, `tf.function`. + + Unlike `tf.function`, `to_graph` is a low-level transpiler that converts + Python code to TensorFlow graph code. It does not implement any caching, + variable management or create any actual ops, and is best used where greater + control over the generated TensorFlow graph is desired. Another difference + from `tf.function` is that `to_graph` will not wrap the graph into a + TensorFlow function or a Python callable. Internally, `tf.function` uses + `to_graph`. + + Example usage: + + >>> def f(x): + ... if x > 0: + ... y = x * x + ... else: + ... y = -x + ... return y + ... + >>> converted_f = to_graph(f) + >>> x = tf.constant(2) + >>> converted_f(x) # converted_foo is like a TensorFlow Op. + + + Supported Python entities include: + * functions + * classes + * object methods + + Functions are converted into new functions with converted code. + + Classes are converted by generating a new class whose methods use converted + code. + + Methods are converted into unbound function that have an additional first + argument called `self`. + + For a tutorial, see the + [tf.function and AutoGraph guide](https://www.tensorflow.org/guide/function). + For more detailed information, see the + [AutoGraph reference documentation](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/g3doc/reference/index.md). + + Args: + entity: Python callable or class to convert. + recursive: Whether to recursively convert any functions that the converted + function may call. + experimental_optional_features: `None`, a tuple of, or a single + `tf.autograph.experimental.Feature` value. + + Returns: + Same as `entity`, the converted Python function or class. + + Raises: + ValueError: If the entity could not be converted. + """ + try: + program_ctx = converter.ProgramContext( + options=converter.ConversionOptions( + recursive=recursive, + user_requested=True, + optional_features=experimental_optional_features)) + return autograph_artifact(_convert_actual(entity, program_ctx)) + except (ValueError, AttributeError, KeyError, NameError, AssertionError) as e: + logging.error(1, 'Error converting %s', entity, exc_info=True) + raise ConversionError('converting {}: {}: {}'.format( + entity, e.__class__.__name__, str(e))) + + +@tf_export(v1=['autograph.to_graph']) +def to_graph_v1(entity, + recursive=True, + arg_values=None, + arg_types=None, + experimental_optional_features=None): + """Converts a Python entity into a TensorFlow graph. + + Also see: `tf.autograph.to_code`, `tf.function`. + + Unlike `tf.function`, `to_graph` is a low-level transpiler that converts + Python code to TensorFlow graph code. It does not implement any caching, + variable management or create any actual ops, and is best used where greater + control over the generated TensorFlow graph is desired. Another difference + from `tf.function` is that `to_graph` will not wrap the graph into a + TensorFlow function or a Python callable. Internally, `tf.function` uses + `to_graph`. + + _Example Usage_ + + ```python + def foo(x): + if x > 0: + y = x * x + else: + y = -x + return y + + converted_foo = to_graph(foo) + + x = tf.constant(1) + y = converted_foo(x) # converted_foo is a TensorFlow Op-like. + assert is_tensor(y) + ``` + + Supported Python entities include: + * functions + * classes + * object methods + + Functions are converted into new functions with converted code. + + Classes are converted by generating a new class whose methods use converted + code. + + Methods are converted into unbound function that have an additional first + argument called `self`. + + Args: + entity: Python callable or class to convert. + recursive: Whether to recursively convert any functions that the converted + function may call. + arg_values: Deprecated. + arg_types: Deprecated. + experimental_optional_features: `None`, a tuple of, or a single + `tf.autograph.experimental.Feature` value. + + Returns: + Same as `entity`, the converted Python function or class. + + Raises: + ValueError: If the entity could not be converted. + """ + del arg_types + del arg_values + return to_graph( + entity, + recursive=recursive, + experimental_optional_features=experimental_optional_features) + + +@tf_export(v1=['autograph.to_code']) +def to_code_v1(entity, + recursive=True, + arg_values=None, + arg_types=None, + indentation=' ', + experimental_optional_features=None): + """Returns the source code generated by AutoGraph, as a string. + + Example usage: + + >>> def f(x): + ... if x < 0: + ... x = -x + ... return x + >>> tf.autograph.to_code(f) + "...def tf__f(x):..." + + Also see: `tf.autograph.to_graph`. + + Note: If a function has been decorated with `tf.function`, pass its + underlying Python function, rather than the callable that `tf.function + creates: + + >>> @tf.function + ... def f(x): + ... if x < 0: + ... x = -x + ... return x + >>> tf.autograph.to_code(f.python_function) + "...def tf__f(x):..." + + Args: + entity: Python callable or class. + recursive: Whether to recursively convert any functions that the converted + function may call. + arg_values: Deprecated. + arg_types: Deprecated. + indentation: Deprecated. + experimental_optional_features: `None`, a tuple of, or a single + `tf.autograph.experimental.Feature` value. + + Returns: + The converted code as string. + """ + del arg_values + del arg_types + del indentation + return to_code( + entity, + recursive=recursive, + experimental_optional_features=experimental_optional_features) + + +@tf_export('autograph.to_code', v1=[]) +def to_code(entity, recursive=True, experimental_optional_features=None): + """Returns the source code generated by AutoGraph, as a string. + + Example usage: + + >>> def f(x): + ... if x < 0: + ... x = -x + ... return x + >>> tf.autograph.to_code(f) + "...def tf__f(x):..." + + Also see: `tf.autograph.to_graph`. + + Note: If a function has been decorated with `tf.function`, pass its + underlying Python function, rather than the callable that `tf.function + creates: + + >>> @tf.function + ... def f(x): + ... if x < 0: + ... x = -x + ... return x + >>> tf.autograph.to_code(f.python_function) + "...def tf__f(x):..." + + Args: + entity: Python callable or class to convert. + recursive: Whether to recursively convert any functions that the converted + function may call. + experimental_optional_features: `None`, a tuple of, or a single + `tf.autograph.experimental.Feature` value. + + Returns: + The converted code as string. + """ + source = tf_inspect.getsource( + to_graph( + entity, + recursive=recursive, + experimental_optional_features=experimental_optional_features)) + return textwrap.dedent(source) + + +_TRANSPILER = PyToTF() diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/conversion.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/conversion.py new file mode 100644 index 0000000000000000000000000000000000000000..b2dd4c678c4c631d4bb9774cc8eec91ba436ce77 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/conversion.py @@ -0,0 +1,227 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Core conversion logic, serves as main point of access.""" + +import functools +import inspect +import sys +import unittest + +from tensorflow.python.autograph.core import config +from tensorflow.python.autograph.pyct import cache +from tensorflow.python.autograph.pyct import inspect_utils +from tensorflow.python.autograph.utils import ag_logging as logging +from tensorflow.python.eager.polymorphic_function import tf_method_target +from tensorflow.python.util import tf_inspect + + +_ALLOWLIST_CACHE = cache.UnboundInstanceCache() + + +def _is_of_known_loaded_module(f, module_name): + mod = sys.modules.get(module_name, None) + if mod is None: + return False + if any(v is not None for v in mod.__dict__.values() if f is v): + return True + return False + + +def _is_known_loaded_type(f, module_name, entity_name): + """Tests whether the function or method is an instance of a known type.""" + if (module_name not in sys.modules or + not hasattr(sys.modules[module_name], entity_name)): + return False + type_entity = getattr(sys.modules[module_name], entity_name) + if isinstance(f, type_entity): + # The method if of this type. Example: + # + # o = ClassType() + # function(o.method)() + return True + # Note: inspect is required here, to avoid unpacking tf.function decorators. + if inspect.ismethod(f): + # The unbound method if of this type. Example: + # + # class ClassType: + # @function + # def method(self): + # ... + # o = ClassType() + # o.method() + if isinstance(f.__func__, type_entity): + return True + return False + + +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 + + +# TODO(mdan): allow_namedtuple_subclass should be hardcoded to True. +def is_allowlisted( + o, check_call_override=True, allow_namedtuple_subclass=False): + """Checks whether an entity is allowed for use in graph mode. + + Examples of allowed entities include all members of the tensorflow + package. + + Args: + o: A Python entity. + check_call_override: Reserved for internal use. When set to `False`, it + disables the rule according to which classes are allowed if their + __call__ method is allowed. + allow_namedtuple_subclass: Reserved for internal use. When `True`, + namedtuple subclasses are not allowed. + + Returns: + Boolean + """ + # TODO(b/120224672): Fix this. + if isinstance(o, functools.partial): + # tf_inspect.getmodule(functools.partial(...)) otherwise returns None since + # functools.partial objects do not have a __module__ attribute. + m = functools + else: + m = tf_inspect.getmodule(o) + + # Examples of callables that lack a __module__ property include builtins. + if hasattr(m, '__name__'): + for rule in config.CONVERSION_RULES: + action = rule.get_action(m) + if action == config.Action.CONVERT: + logging.log(2, 'Not allowed: %s: %s', o, rule) + return False + elif action == config.Action.DO_NOT_CONVERT: + logging.log(2, 'Allowlisted: %s: %s', o, rule) + return True + + # The check for __code__ below is because isgeneratorfunction crashes + # without one. + if hasattr(o, '__code__') and tf_inspect.isgeneratorfunction(o): + logging.log(2, 'Allowlisted: %s: generator functions are not converted', o) + return True + + if (check_call_override and not tf_inspect.isclass(o) and + hasattr(o, '__call__')): + # Callable objects: allowed if their __call__ method is. + # The type check avoids infinite recursion around the __call__ method + # of function objects. + if (type(o) != type(o.__call__)) and is_allowlisted(o.__call__): # pylint: disable=unidiomatic-typecheck + logging.log(2, 'Allowlisted: %s: object __call__ allowed', o) + return True + + owner_class = None + if tf_inspect.ismethod(o): + # Methods of allowed classes are also allowed, even if they are + # bound via user subclasses. + # + # For example, suppose `tf.Foo` has a method called `bar`, and `baz` is + # defined as below. `tf.Foo` is allowed. Then `baz.bar` is also + # allowed. + # + # class Custom(tf.Foo): + # pass + # + # baz = Custom() + # + # For the example above, if `Custom` did overload `bar`, then it would no + # longer be allowed. + + owner_class = inspect_utils.getmethodclass(o) + if owner_class is tf_method_target.TfMethodTarget: + owner_class = o.__self__.target_class + if owner_class is not None: + if issubclass(owner_class, unittest.TestCase): + logging.log(2, 'Allowlisted: %s: method of TestCase subclass', o) + return True + + owner_class = inspect_utils.getdefiningclass(o, owner_class) + if is_allowlisted( + owner_class, + check_call_override=False, + allow_namedtuple_subclass=True): + logging.log(2, 'Allowlisted: %s: owner is allowed %s', o, + owner_class) + return True + + if inspect_utils.isnamedtuple(o): + # Due to the way they're constructed, namedtuple types cannot be converted + # because they don't expose source code. But we assume they are safe for + # graph mode since they are just containers. + if allow_namedtuple_subclass: + if not any(inspect_utils.isnamedtuple(base) for base in o.__bases__): + logging.log(2, 'Allowlisted: %s: named tuple', o) + return True + else: + logging.log(2, 'Allowlisted: %s: named tuple or subclass', o) + return True + + logging.log(2, 'Not allowed: %s: default rule', o) + return False + + +def is_in_allowlist_cache(entity, options): + try: + return _ALLOWLIST_CACHE.has(entity, options) + except TypeError: + # Catch-all for entities that are unhashable or don't allow weakrefs. + return False + + +def cache_allowlisted(entity, options): + try: + _ALLOWLIST_CACHE[entity][options] = True + except TypeError: + # Catch-all for entities that are unhashable or don't allow weakrefs. + pass diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ad9fb181871c63bd636ec541f7e01de53ced904 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72478b358ad45f5223b09f44cdb3dc839c41d339 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/anf.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/anf.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8450ce38e2aeb7d2a5fab407fdd5192bd3be3483 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/__pycache__/anf.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/anf.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/anf.py new file mode 100644 index 0000000000000000000000000000000000000000..71ba9f35d7847e359a7c207ac9f89e86ec8e6639 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/common_transformers/anf.py @@ -0,0 +1,620 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Conversion to A-normal form. + +The general idea of A-normal form is that every intermediate value is +explicitly named with a variable. For more, see +https://en.wikipedia.org/wiki/A-normal_form. + +The specific converters used here are based on Python AST semantics as +documented at https://greentreesnakes.readthedocs.io/en/latest/. +""" + +import collections + +import gast + +from tensorflow.python.autograph.pyct import gast_util +from tensorflow.python.autograph.pyct import templates +from tensorflow.python.autograph.pyct import transformer + + +# TODO(mdan): Replace with naming.Namer. +class DummyGensym: + """A dumb gensym that suffixes a stem by sequential numbers from 1000.""" + + def __init__(self): + # A proper implementation needs to account for: + # * ctx.info.namespace + # * all the symbols defined in the AST + # * the symbols generated so far + self._idx = 0 + + def new_name(self, stem='tmp'): + self._idx += 1 + return stem + '_' + str(1000 + self._idx) + + +REPLACE = lambda _1, _2, _3: True +LEAVE = lambda _1, _2, _3: False +ANY = object() + + +class ASTEdgePattern(collections.namedtuple( + 'ASTEdgePattern', ['parent', 'field', 'child'])): + """A pattern defining a type of AST edge. + + This consists of three components: + - The type of the parent node, checked with isinstance, + - The name of the field, checked with string equality, and + - The type of the child node, also checked with isinstance. + If all three match, the whole pattern is considered to match. + + In all three slots, the special value `anf.ANY` is treated as "match + anything". The internal nodes are produced from the `gast` library rather + than the standard `ast` module, which may affect `isinstance` checks. + """ + __slots__ = () + + def matches(self, parent, field, child): + """Computes whether this pattern matches the given edge.""" + if self.parent is ANY or isinstance(parent, self.parent): + pass # OK + else: + return False + if self.field is ANY or field == self.field: + pass # OK + else: + return False + return self.child is ANY or isinstance(child, self.child) + + +class AnfTransformer(transformer.Base): + """Performs the conversion to A-normal form (ANF).""" + + # The algorithm is a postorder recursive tree walk. Any given node A may, in + # general, require creation of a series B of Assign statements, which compute + # and explicitly name the intermediate values needed to compute the value of + # A. If A was already a statement, it can be replaced with the sequence B + + # [A]. If A was an expression, B needs to be propagated up the tree until a + # statement is encountered. Since the `ast.NodeTransformer` framework makes + # no provision for subtraversals returning side information, this class + # accumulates the sequence B in an instance variable. + + # The only other subtlety is that some Python statements (like `if`) have both + # expression fields (`test`) and statement list fields (`body` and `orelse`). + # Any additional assignments needed to name all the intermediate values in the + # `test` can be prepended to the `if` node, but assignments produced by + # processing the `body` and the `orelse` need to be kept together with them, + # and not accidentally lifted out of the `if`. + + def __init__(self, ctx, config): + """Creates an ANF transformer. + + Args: + ctx: transformer.Context + config: Configuration + """ + super(AnfTransformer, self).__init__(ctx) + if config is None: + # These could be pulled out, but are generally considered to already be in + # A-normal form. Thus they are left in by default, but could be pulled + # out if the configuration calls for it. + if gast_util.GAST2: + literal_node_types = ( + gast.Num, gast.Str, gast.Bytes, gast.NameConstant, + gast.Name # Name is here to cover True, False, and None in Python 2 + ) + elif gast_util.GAST3: + literal_node_types = ( + gast.Constant, + gast.Name # Name is here to cover True, False, and None in Python 2 + ) + else: + assert False + + self._overrides = [ + (ASTEdgePattern(ANY, ANY, literal_node_types), LEAVE), + (ASTEdgePattern(ANY, ANY, gast.expr), REPLACE)] + else: + self._overrides = config + self._gensym = DummyGensym() + self._pending_statements = [] + + def _consume_pending_statements(self): + ans = self._pending_statements + self._pending_statements = [] + return ans + + def _add_pending_statement(self, stmt): + self._pending_statements.append(stmt) + + def _match(self, pattern, parent, field, child): + if pattern is ANY: + return True + else: + return pattern.matches(parent, field, child) + + def _should_transform(self, parent, field, child): + for pat, result in self._overrides: + if self._match(pat, parent, field, child): + return result(parent, field, child) + # Fell off the end of the pattern list: do not transform + return False + + def _do_transform_node(self, node): + temp_name = self._gensym.new_name() + temp_assign = templates.replace( + 'temp_name = expr', temp_name=temp_name, expr=node)[0] + self._add_pending_statement(temp_assign) + answer = templates.replace('temp_name', temp_name=temp_name)[0] + return answer + + def _ensure_node_in_anf(self, parent, field, node): + """Puts `node` in A-normal form, by replacing it with a variable if needed. + + The exact definition of A-normal form is given by the configuration. The + parent and the incoming field name are only needed because the configuration + may be context-dependent. + + Args: + parent: An AST node, the parent of `node`. + field: The field name under which `node` is the child of `parent`. + node: An AST node, potentially to be replaced with a variable reference. + + Returns: + node: An AST node; the argument if transformation was not necessary, + or the new variable reference if it was. + """ + if node is None: + return node + if _is_trivial(node): + return node + if isinstance(node, list): + # If something's field was actually a list, e.g., variadic arguments. + return [self._ensure_node_in_anf(parent, field, n) for n in node] + if isinstance(node, gast.keyword): + node.value = self._ensure_node_in_anf(parent, field, node.value) + return node + if isinstance(node, (gast.Starred, gast.withitem, gast.slice)): + # These nodes aren't really extractable in their own right, but their + # subnodes might be. Propagate the parent and field name to the child + # nodes, instead of querying the configuration for children of, e.g., + # gast.Starred. + return self._ensure_fields_in_anf(node, parent, field) + if self._should_transform(parent, field, node): + return self._do_transform_node(node) + else: + return node + + def _ensure_fields_in_anf(self, node, parent=None, super_field=None): + for field in node._fields: + if field.startswith('__'): + continue + parent_supplied = node if parent is None else parent + field_supplied = field if super_field is None else super_field + setattr(node, field, self._ensure_node_in_anf( + parent_supplied, field_supplied, getattr(node, field))) + return node + + def _visit_strict_statement(self, node, children_ok_to_transform=True): + assert not self._pending_statements + node = self.generic_visit(node) + if children_ok_to_transform: + self._ensure_fields_in_anf(node) + results = self._consume_pending_statements() + results.append(node) + return results + + def _visit_trivial_only_statement(self, node, msg): + assert not self._pending_statements + node = self.generic_visit(node) + self._ensure_fields_in_anf(node) + if self._pending_statements: + raise ValueError(msg) + else: + return node + + def _visit_strict_expression(self, node): + node = self.generic_visit(node) + self._ensure_fields_in_anf(node) + return node + + def _visit_trivial_only_expression(self, node, msg): + k = len(self._pending_statements) + node = self.generic_visit(node) + self._ensure_fields_in_anf(node) + # This check relies on there being no opportunities to consume pending + # statements while traversing children of an expression. + if len(self._pending_statements) != k: + raise ValueError(msg) + else: + return node + + # Note on code order: These are listed in the same order as the grammar + # elements on https://github.com/serge-sans-paille/gast + + # FunctionDef, AsyncFunctionDef, and ClassDef should be correct by default. + + def visit_Return(self, node): + return self._visit_strict_statement(node) + + def visit_Delete(self, node): + return self._visit_strict_statement(node, children_ok_to_transform=False) + + def visit_Assign(self, node): + return self._visit_strict_statement(node, children_ok_to_transform=False) + + def visit_AugAssign(self, node): + return self._visit_strict_statement(node, children_ok_to_transform=False) + + def visit_Print(self, node): + return self._visit_strict_statement(node) + + def visit_For(self, node): + assert not self._pending_statements + # It's important to visit node.iter first, because any statements created + # thereby need to live outside the body. + self.visit(node.iter) + node.iter = self._ensure_node_in_anf(node, 'iter', node.iter) + iter_stmts = self._consume_pending_statements() + # This generic_visit will revisit node.iter, but that is correct because by + # this point the node.iter link has been checked. It may be somewhat + # expensive if the configuration didn't call for transforming node.iter, as + # then it may be large and will be uselessly transformed again. This + # behavior is what causes the documented effect that configuration callables + # may be invoked more than once of the same links; if the code is rewritten + # not to do that (anywhere), the docstring of `transform` should be updated. + node = self.generic_visit(node) + assert not self._pending_statements + iter_stmts.append(node) + return iter_stmts + + def visit_AsyncFor(self, node): + msg = ('Nontrivial AsyncFor nodes not supported yet ' + '(need to think through the semantics).') + return self._visit_trivial_only_statement(node, msg) + + def visit_While(self, node): + assert not self._pending_statements + self.visit(node.test) + node.test = self._ensure_node_in_anf(node, 'test', node.test) + if self._pending_statements: + msg = ('While with nontrivial test not supported yet ' + '(need to avoid precomputing the test).') + raise ValueError(msg) + # If traversing node.test yielded no statements extracted, the generic visit + # will do the right thing. + return self.generic_visit(node) + + def visit_If(self, node): + assert not self._pending_statements + # It's important to visit node.test first, because any statements created + # thereby need to live outside the body. + self.visit(node.test) + node.test = self._ensure_node_in_anf(node, 'test', node.test) + condition_stmts = self._consume_pending_statements() + # This generic_visit will revisit node.test, but that is correct because by + # this point the node.test link has been checked. It may be somewhat + # expensive if the configuration didn't call for transforming node.test, as + # then it may be large and will be uselessly transformed again. This + # happens in several places. + node = self.generic_visit(node) + assert not self._pending_statements + condition_stmts.append(node) + return condition_stmts + + def visit_With(self, node): + assert not self._pending_statements + # It's important to visit node.items first, because any statements created + # thereby need to live outside the body. + for item in node.items: + self.visit(item) + node.items = [self._ensure_node_in_anf(node, 'items', n) + for n in node.items] + contexts_stmts = self._consume_pending_statements() + # This generic_visit will revisit node.items, but that is correct because by + # this point the node.items link has been checked. It may be somewhat + # expensive if the configuration didn't call for transforming node.items, as + # then it may be large and will be uselessly transformed again. This + # happens in several places. + node = self.generic_visit(node) + assert not self._pending_statements + contexts_stmts.append(node) + return contexts_stmts + + def visit_AsyncWith(self, node): + msg = ('Nontrivial AsyncWith nodes not supported yet ' + '(need to think through the semantics).') + return self._visit_trivial_only_statement(node, msg) + + def visit_Raise(self, node): + return self._visit_strict_statement(node) + + # Try should be correct by default. + + def visit_Assert(self, node): + msg = ('Nontrivial Assert nodes not supported yet ' + '(need to avoid computing the test when assertions are off, and ' + 'avoid computing the irritant when the assertion does not fire).') + return self._visit_trivial_only_statement(node, msg) + + # Import and ImportFrom should be correct by default. + + def visit_Exec(self, node): + return self._visit_strict_statement(node) + + # Global and Nonlocal should be correct by default. + + def visit_Expr(self, node): + return self._visit_strict_statement(node, children_ok_to_transform=False) + + # Pass, Break, and Continue should be correct by default. + + def visit_BoolOp(self, node): + msg = ('Nontrivial BoolOp nodes not supported yet ' + '(need to preserve short-circuiting semantics).') + return self._visit_trivial_only_expression(node, msg) + + def visit_BinOp(self, node): + return self._visit_strict_expression(node) + + def visit_UnaryOp(self, node): + return self._visit_strict_expression(node) + + def visit_Lambda(self, node): + msg = ('Nontrivial Lambda nodes not supported ' + '(cannot insert statements into lambda bodies).') + return self._visit_trivial_only_expression(node, msg) + + def visit_IfExp(self, node): + msg = ('Nontrivial IfExp nodes not supported yet ' + '(need to convert to If statement, to evaluate branches lazily ' + 'and insert statements into them).') + return self._visit_trivial_only_expression(node, msg) + + def visit_Dict(self, node): + return self._visit_strict_expression(node) + + def visit_Set(self, node): + return self._visit_strict_expression(node) + + def visit_ListComp(self, node): + msg = ('ListComp nodes not supported ' + '(need to convert to a form that tolerates ' + 'assignment statements in clause bodies).') + raise ValueError(msg) + + def visit_SetComp(self, node): + msg = ('SetComp nodes not supported ' + '(need to convert to a form that tolerates ' + 'assignment statements in clause bodies).') + raise ValueError(msg) + + def visit_DictComp(self, node): + msg = ('DictComp nodes not supported ' + '(need to convert to a form that tolerates ' + 'assignment statements in clause bodies).') + raise ValueError(msg) + + def visit_GeneratorExp(self, node): + msg = ('GeneratorExp nodes not supported ' + '(need to convert to a form that tolerates ' + 'assignment statements in clause bodies).') + raise ValueError(msg) + + def visit_Await(self, node): + msg = ('Nontrivial Await nodes not supported yet ' + '(need to think through the semantics).') + return self._visit_trivial_only_expression(node, msg) + + def visit_Yield(self, node): + return self._visit_strict_expression(node) + + def visit_YieldFrom(self, node): + msg = ('Nontrivial YieldFrom nodes not supported yet ' + '(need to unit-test them in Python 2).') + return self._visit_trivial_only_expression(node, msg) + + def visit_Compare(self, node): + if len(node.ops) > 1: + msg = ('Multi-ary compare nodes not supported yet ' + '(need to preserve short-circuiting semantics).') + raise ValueError(msg) + return self._visit_strict_expression(node) + + def visit_Call(self, node): + return self._visit_strict_expression(node) + + def visit_Repr(self, node): + msg = ('Nontrivial Repr nodes not supported yet ' + '(need to research their syntax and semantics).') + return self._visit_trivial_only_expression(node, msg) + + def visit_FormattedValue(self, node): + msg = ('Nontrivial FormattedValue nodes not supported yet ' + '(need to unit-test them in Python 2).') + return self._visit_trivial_only_expression(node, msg) + + def visit_JoinedStr(self, node): + msg = ('Nontrivial JoinedStr nodes not supported yet ' + '(need to unit-test them in Python 2).') + return self._visit_trivial_only_expression(node, msg) + + def visit_Attribute(self, node): + return self._visit_strict_expression(node) + + def visit_Subscript(self, node): + return self._visit_strict_expression(node) + + # Starred and Name are correct by default, because the right thing to do is to + # just recur. + + def visit_List(self, node): + node = self.generic_visit(node) + if not isinstance(node.ctx, gast.Store): + self._ensure_fields_in_anf(node) + return node + + def visit_Tuple(self, node): + node = self.generic_visit(node) + if not isinstance(node.ctx, gast.Store): + self._ensure_fields_in_anf(node) + return node + + +def _is_py2_name_constant(node): + return isinstance(node, gast.Name) and node.id in ['True', 'False', 'None'] + + +def _is_trivial(node): + """Returns whether to consider the given node 'trivial'. + + The definition of 'trivial' is a node that can't meaningfully be pulled out + into its own assignment statement. + + This is surprisingly difficult to do robustly across versions of Python and + gast, as the parsing of constants has changed, if I may, constantly. + + Args: + node: An AST node to check for triviality + + Returns: + trivial: A Python `bool` indicating whether the node is trivial. + """ + trivial_node_types = ( + # Variable names + gast.Name, + # Non-nodes that show up as AST fields + bool, + str, + # Binary operators + gast.Add, + gast.Sub, + gast.Mult, + gast.Div, + gast.Mod, + gast.Pow, + gast.LShift, + gast.RShift, + gast.BitOr, + gast.BitXor, + gast.BitAnd, + gast.FloorDiv, + # Unary operators + gast.Invert, + gast.Not, + gast.UAdd, + gast.USub, + # Comparison operators + gast.Eq, + gast.NotEq, + gast.Lt, + gast.LtE, + gast.Gt, + gast.GtE, + gast.Is, + gast.IsNot, + gast.In, + gast.NotIn, + # Other leaf nodes that don't make sense standalone. + gast.expr_context, + ) + if isinstance(node, trivial_node_types) and not _is_py2_name_constant(node): + return True + if gast_util.is_ellipsis(node): + return True + + return False + + +def transform(node, ctx, config=None): + """Converts the given node to A-normal form (ANF). + + The general idea of A-normal form: https://en.wikipedia.org/wiki/A-normal_form + + The specific converters used here are based on Python AST semantics as + documented at https://greentreesnakes.readthedocs.io/en/latest/. + + What exactly should be considered A-normal form for any given programming + language is not completely obvious. The transformation defined here is + therefore configurable as to which syntax to replace with a fresh variable and + which to leave be. The configuration is intentionally flexible enough to + define very precise variable insertion transformations, should that be + desired. + + The configuration is a list of syntax rules, each of which is a 2-tuple: + - An `ASTEdgePattern` (which see) defining a type of AST edge, and + - Whether to transform children of such edges. + The special object `anf.ANY` may be used as a pattern that matches all edges. + + Each replacement directive is one of three possible things: + - The object `anf.REPLACE`, meaning "Replace this child node with a variable", + - The object `anf.LEAVE`, meaning "Do not replace this child node with a + variable", or + - A Python callable. If a callable, it is called with the parent node, the + field name, and the child node, and must compute a boolean indicating + whether to transform the child node or not. The callable is free to use + whatever context information it chooses. The callable may be invoked more + than once on the same link, and must produce the same answer each time. + + The syntax rules are tested in order, and the first match governs. If no rule + matches, the node is not transformed. + + The above rules notwithstanding, + - Variable references are never replaced with (fresh) variables, as that would + accomplish nothing. + - The left-hand children of Assign and AugAssign nodes, and the children of + Del nodes, are never replaced with variables, as that would break their + semantics. + - The right-hand children of Assign nodes are never replaced with variables, + as the original assignment would still have to be present in the result + to define the new variable. (That is, there's no point in transforming + `x = sin(y)` into `tmp = sin(y); x = tmp`.) + - The right-hand children of AugAssign nodes are never replaced with variables + either, but only because the difference from Assign was considered a + potential source of confusion (and it would have been slightly awkward in + the code to treat the RHS differently than the LHS). + - Various special-purpose AST nodes are not exposed to the configuration, lest + the transform produce invalid syntax like, e.g., `tmp = +; x = 1 tmp 2`. + + For example, the configuration + ```python + [(anf.ASTEdgePattern(anf.ANY, anf.ANY, gast.expr), anf.REPLACE)] + ``` + gives explicit fresh names to all expressions regardless of context (except as + outlined above), whereas + ```python + [(anf.ASTEdgePattern(gast.If, "test", anf.ANY), anf.REPLACE)] + ``` + only transforms the conditionals of `if` statements (but not, e.g., `while`). + + If no configuration is supplied, the default behavior is to transform all + expressions except literal constants, which is defined as a configuration as + ```python + # For Python 3, and gast library versions before 0.3 + literals = (gast.Num, gast.Str, gast.Bytes, gast.NameConstant) + [(anf.ASTEdgePattern(anf.ANY, anf.ANY, literals), anf.LEAVE), + (anf.ASTEdgePattern(anf.ANY, anf.ANY, gast.expr), anf.REPLACE)] + ``` + + Args: + node: The node to transform. + ctx: transformer.EntityInfo. TODO(mdan): What information does this + argument provide? + config: Optional ANF configuration. If omitted, ANF replaces all expression + expect literal constants. + """ + return AnfTransformer(ctx, config).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9e61005aac0fce4cdbfc98030721d2db929ea0 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/activity.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/activity.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d69a809594a8a22af874ccbbefaa47fa06e99839 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/activity.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/annos.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/annos.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddec4a1554a03635d1b82fb9827de1a83c285179 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/annos.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/liveness.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/liveness.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3343688863866924a87765aeee76ac7045fe69e5 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/liveness.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_definitions.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_definitions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14cef5140cb0cd9d6b3b45a2bc322ec004d5857b Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_definitions.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_fndefs.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_fndefs.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb58851108ec6888de6eda8781815746101bccf1 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/reaching_fndefs.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/type_inference.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/type_inference.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7f111b49737a617cd9ff9d09d541ff52190a1d3 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/__pycache__/type_inference.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/activity.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/activity.py new file mode 100644 index 0000000000000000000000000000000000000000..5d6a8725c7cea286563b455f484d1e6d5a3a2468 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/activity.py @@ -0,0 +1,706 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Activity analysis. + +Requires qualified name annotations (see qual_names.py). +""" + +import copy +import weakref + +import gast + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import transformer +from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno + + +class Scope(object): + """Encloses local symbol definition and usage information. + + This can track for instance whether a symbol is modified in the current scope. + Note that scopes do not necessarily align with Python's scopes. For example, + the body of an if statement may be considered a separate scope. + + Caution - the AST references held by this object are weak. + + Scope objects are mutable during construction only, and must be frozen using + `Scope.finalize()` before use. Furthermore, a scope is consistent only after + all its children have been frozen. While analysing code blocks, scopes are + being gradually built, from the innermost scope outward. Freezing indicates + that the analysis of a code block is complete. Once frozen, mutation is no + longer allowed. `is_final` tracks whether the scope is frozen or not. Certain + properties, like `referenced`, are only accurate when called on frozen scopes. + + Attributes: + parent: Optional[Scope], the parent scope, if any. + isolated: bool, whether the scope is a true Python scope (e.g. the scope of + a function), or just a surrogate tracking an ordinary code block. Using + the terminology of the Python 3 reference documentation, True roughly + represents an actual scope, whereas False represents an ordinary code + block. + function_name: Optional[str], name of the function owning this scope. + isolated_names: Set[qual_names.QN], identifiers that are isolated to this + scope (even if the scope is not isolated). + annotations: Set[qual_names.QN], identifiers used as type annotations + in this scope. + read: Set[qual_names.QN], identifiers read in this scope. + modified: Set[qual_names.QN], identifiers modified in this scope. + deleted: Set[qual_names.QN], identifiers deleted in this scope. + bound: Set[qual_names.QN], names that are bound to this scope. See + https://docs.python.org/3/reference/executionmodel.html#binding-of-names + for a precise definition. + globals: Set[qual_names.QN], names that are explicitly marked as global in + this scope. Note that this doesn't include free read-only vars bound to + global symbols. + nonlocals: Set[qual_names.QN], names that are explicitly marked as nonlocal + in this scope. Note that this doesn't include free read-only vars bound to + global symbols. + free_vars: Set[qual_names.QN], the free variables in this scope. See + https://docs.python.org/3/reference/executionmodel.html for a precise + definition. + params: WeakValueDictionary[qual_names.QN, ast.Node], function arguments + visible in this scope, mapped to the function node that defines them. + enclosing_scope: Scope, the innermost isolated scope that is a transitive + parent of this scope. May be the scope itself. + referenced: Set[qual_names.QN], the totality of the symbols used by this + scope and its parents. + is_final: bool, whether the scope is frozen or not. + + Note - simple statements may never delete and modify a symbol at the same + time. However, compound ones like if statements can. In that latter case, it's + undefined whether the symbol is actually modified or deleted upon statement + exit. Certain analyses like reaching definitions need to be careful about + this. + """ + + # Note: this mutable-immutable pattern is used because using a builder would + # have taken a lot more boilerplate. + + def __init__(self, parent, isolated=True, function_name=None): + """Create a new scope. + + Args: + parent: A Scope or None. + isolated: Whether the scope is isolated, that is, whether variables + modified in this scope should be considered modified in the parent + scope. + function_name: Name of the function owning this scope. + """ + self.parent = parent + self.isolated = isolated + self.function_name = function_name + + self.isolated_names = set() + + self.read = set() + self.modified = set() + self.deleted = set() + + self.bound = set() + self.globals = set() + self.nonlocals = set() + self.annotations = set() + + self.params = weakref.WeakValueDictionary() + + # Certain fields can only be accessed after the scope and all its parent + # scopes have been fully built. This field guards that. + self.is_final = False + + @property + def enclosing_scope(self): + assert self.is_final + if self.parent is not None and not self.isolated: + return self.parent + return self + + @property + def referenced(self): + if self.parent is not None: + return self.read | self.parent.referenced + return self.read + + @property + def free_vars(self): + enclosing_scope = self.enclosing_scope + return enclosing_scope.read - enclosing_scope.bound + + def copy_from(self, other): + """Recursively copies the contents of this scope from another scope.""" + assert not self.is_final + if self.parent is not None: + assert other.parent is not None + self.parent.copy_from(other.parent) + self.isolated_names = copy.copy(other.isolated_names) + self.modified = copy.copy(other.modified) + self.read = copy.copy(other.read) + self.deleted = copy.copy(other.deleted) + self.bound = copy.copy(other.bound) + self.annotations = copy.copy(other.annotations) + self.params = copy.copy(other.params) + + @classmethod + def copy_of(cls, other): + if other.parent is not None: + assert other.parent is not None + parent = cls.copy_of(other.parent) + else: + parent = None + new_copy = cls(parent) + new_copy.copy_from(other) + return new_copy + + def merge_from(self, other): + """Adds all activity from another scope to this scope.""" + assert not self.is_final + if self.parent is not None: + assert other.parent is not None + self.parent.merge_from(other.parent) + self.isolated_names.update(other.isolated_names) + self.read.update(other.read) + self.modified.update(other.modified) + self.bound.update(other.bound) + self.deleted.update(other.deleted) + self.annotations.update(other.annotations) + self.params.update(other.params) + + def finalize(self): + """Freezes this scope.""" + assert not self.is_final + # TODO(mdan): freeze read, modified, bound. + if self.parent is not None: + assert not self.parent.is_final + if not self.isolated: + self.parent.read.update(self.read - self.isolated_names) + self.parent.modified.update(self.modified - self.isolated_names) + self.parent.bound.update(self.bound - self.isolated_names) + self.parent.globals.update(self.globals) + self.parent.nonlocals.update(self.nonlocals) + self.parent.annotations.update(self.annotations) + else: + # TODO(mdan): This is not accurate. + self.parent.read.update(self.read - self.bound) + self.parent.annotations.update(self.annotations - self.bound) + self.is_final = True + + def __repr__(self): + return 'Scope{r=%s, w=%s}' % (tuple(self.read), tuple(self.modified)) + + def mark_param(self, name, owner): + # Assumption: all AST nodes have the same life span. This lets us use + # a weak reference to mark the connection between a symbol node and the + # function node whose argument that symbol is. + self.params[name] = owner + + +class _Comprehension(object): + + no_root = True + + def __init__(self): + # TODO(mdan): Consider using an enum. + self.is_list_comp = False + self.targets = set() + + +class _FunctionOrClass(object): + + def __init__(self): + self.node = None + + +class ActivityAnalyzer(transformer.Base): + """Annotates nodes with local scope information. + + See Scope. + + The use of this class requires that qual_names.resolve() has been called on + the node. This class will ignore nodes have not been + annotated with their qualified names. + """ + + def __init__(self, context, parent_scope=None): + super(ActivityAnalyzer, self).__init__(context) + self.allow_skips = False + self.scope = Scope(parent_scope, isolated=True) + + # Note: all these flags crucially rely on the respective nodes are + # leaves in the AST, that is, they cannot contain other statements. + self._in_aug_assign = False + self._in_annotation = False + self._track_annotations_only = False + + @property + def _in_constructor(self): + context = self.state[_FunctionOrClass] + if context.level > 2: + innermost = context.stack[-1].node + parent = context.stack[-2].node + return (isinstance(parent, gast.ClassDef) and + (isinstance(innermost, gast.FunctionDef) and + innermost.name == '__init__')) + return False + + def _node_sets_self_attribute(self, node): + if anno.hasanno(node, anno.Basic.QN): + qn = anno.getanno(node, anno.Basic.QN) + # TODO(mdan): The 'self' argument is not guaranteed to be called 'self'. + if qn.has_attr and qn.parent.qn == ('self',): + return True + return False + + def _track_symbol(self, node, composite_writes_alter_parent=False): + if self._track_annotations_only and not self._in_annotation: + return + + # A QN may be missing when we have an attribute (or subscript) on a function + # call. Example: a().b + if not anno.hasanno(node, anno.Basic.QN): + return + qn = anno.getanno(node, anno.Basic.QN) + + # When inside a comprehension, ignore reads to any of the comprehensions's + # targets. This includes attributes or slices of those arguments. + for l in self.state[_Comprehension]: + if qn in l.targets: + return + if qn.owner_set & set(l.targets): + return + + if isinstance(node.ctx, gast.Store): + # In comprehensions, modified symbols are the comprehension targets. + if self.state[_Comprehension].level > 0: + self.state[_Comprehension].targets.add(qn) + return + + self.scope.modified.add(qn) + self.scope.bound.add(qn) + if qn.is_composite and composite_writes_alter_parent: + self.scope.modified.add(qn.parent) + if self._in_aug_assign: + self.scope.read.add(qn) + + elif isinstance(node.ctx, gast.Load): + self.scope.read.add(qn) + if self._in_annotation: + self.scope.annotations.add(qn) + + elif isinstance(node.ctx, gast.Param): + self.scope.bound.add(qn) + self.scope.mark_param(qn, self.state[_FunctionOrClass].node) + + elif isinstance(node.ctx, gast.Del): + # The read matches the Python semantics - attempting to delete an + # undefined symbol is illegal. + self.scope.read.add(qn) + # Targets of del are considered bound: + # https://docs.python.org/3/reference/executionmodel.html#binding-of-names + self.scope.bound.add(qn) + self.scope.deleted.add(qn) + + else: + raise ValueError('Unknown context {} for node "{}".'.format( + type(node.ctx), qn)) + + def _enter_scope(self, isolated, f_name=None): + self.scope = Scope(self.scope, isolated=isolated, function_name=f_name) + + def _exit_scope(self): + exited_scope = self.scope + exited_scope.finalize() + self.scope = exited_scope.parent + return exited_scope + + def _exit_and_record_scope(self, node, tag=anno.Static.SCOPE): + node_scope = self._exit_scope() + anno.setanno(node, tag, node_scope) + return node_scope + + def _process_statement(self, node): + self._enter_scope(False) + node = self.generic_visit(node) + self._exit_and_record_scope(node) + return node + + def _process_annotation(self, node): + self._in_annotation = True + node = self.visit(node) + self._in_annotation = False + return node + + def visit_Import(self, node): + return self._process_statement(node) + + def visit_ImportFrom(self, node): + return self._process_statement(node) + + def visit_Global(self, node): + self._enter_scope(False) + for name in node.names: + qn = qual_names.QN(name) + self.scope.read.add(qn) + self.scope.globals.add(qn) + self._exit_and_record_scope(node) + return node + + def visit_Nonlocal(self, node): + self._enter_scope(False) + for name in node.names: + qn = qual_names.QN(name) + self.scope.read.add(qn) + self.scope.bound.add(qn) + self.scope.nonlocals.add(qn) + self._exit_and_record_scope(node) + return node + + def visit_Expr(self, node): + return self._process_statement(node) + + def visit_Raise(self, node): + return self._process_statement(node) + + def visit_Return(self, node): + return self._process_statement(node) + + def visit_Assign(self, node): + return self._process_statement(node) + + def visit_AnnAssign(self, node): + self._enter_scope(False) + node.target = self.visit(node.target) + if node.value is not None: + # Can be None for pure declarations, e.g. `n: int`. This is a new thing + # enabled by type annotations, but does not influence static analysis + # (declarations are not definitions). + node.value = self.visit(node.value) + if node.annotation: + node.annotation = self._process_annotation(node.annotation) + self._exit_and_record_scope(node) + return node + + def visit_AugAssign(self, node): + # Special rules for AugAssign. Here, the AST only shows the target as + # written, when it is in fact also read. + self._enter_scope(False) + + self._in_aug_assign = True + node.target = self.visit(node.target) + self._in_aug_assign = False + + node.op = self.visit(node.op) + node.value = self.visit(node.value) + self._exit_and_record_scope(node) + return node + + def visit_Delete(self, node): + return self._process_statement(node) + + def visit_Name(self, node): + if node.annotation: + node.annotation = self._process_annotation(node.annotation) + self._track_symbol(node) + return node + + def visit_alias(self, node): + node = self.generic_visit(node) + + if node.asname is None: + # Only the root name is a real symbol operation. + qn = qual_names.QN(node.name.split('.')[0]) + else: + qn = qual_names.QN(node.asname) + + self.scope.modified.add(qn) + self.scope.bound.add(qn) + return node + + def visit_Attribute(self, node): + node = self.generic_visit(node) + if self._in_constructor and self._node_sets_self_attribute(node): + self._track_symbol(node, composite_writes_alter_parent=True) + else: + self._track_symbol(node) + return node + + def visit_Subscript(self, node): + node = self.generic_visit(node) + # Subscript writes (e.g. a[b] = "value") are considered to modify + # both the element itself (a[b]) and its parent (a). + self._track_symbol(node) + return node + + def visit_Print(self, node): + self._enter_scope(False) + node.values = self.visit_block(node.values) + node_scope = self._exit_and_record_scope(node) + anno.setanno(node, NodeAnno.ARGS_SCOPE, node_scope) + return node + + def visit_Assert(self, node): + return self._process_statement(node) + + def visit_Call(self, node): + self._enter_scope(False) + node.args = self.visit_block(node.args) + node.keywords = self.visit_block(node.keywords) + # TODO(mdan): Account starargs, kwargs + self._exit_and_record_scope(node, tag=NodeAnno.ARGS_SCOPE) + + node.func = self.visit(node.func) + return node + + def _process_block_node(self, node, block, scope_name): + self._enter_scope(False) + block = self.visit_block(block) + self._exit_and_record_scope(node, tag=scope_name) + return node + + def _process_parallel_blocks(self, parent, children): + # Because the scopes are not isolated, processing any child block + # modifies the parent state causing the other child blocks to be + # processed incorrectly. So we need to checkpoint the parent scope so that + # each child sees the same context. + before_parent = Scope.copy_of(self.scope) + after_children = [] + for child, scope_name in children: + self.scope.copy_from(before_parent) + parent = self._process_block_node(parent, child, scope_name) + after_child = Scope.copy_of(self.scope) + after_children.append(after_child) + for after_child in after_children: + self.scope.merge_from(after_child) + return parent + + def _process_comprehension(self, + node, + is_list_comp=False, + is_dict_comp=False): + with self.state[_Comprehension] as comprehension_: + comprehension_.is_list_comp = is_list_comp + # Note: it's important to visit the generators first to properly account + # for the variables local to these generators. Example: `x` is local to + # the expression `z for x in y for z in x`. + node.generators = self.visit_block(node.generators) + if is_dict_comp: + node.key = self.visit(node.key) + node.value = self.visit(node.value) + else: + node.elt = self.visit(node.elt) + return node + + def visit_comprehension(self, node): + # It is important to visit children in this order so that the reads to + # the target name are appropriately ignored. + node.iter = self.visit(node.iter) + node.target = self.visit(node.target) + return self.generic_visit(node) + + def visit_DictComp(self, node): + return self._process_comprehension(node, is_dict_comp=True) + + def visit_ListComp(self, node): + return self._process_comprehension(node, is_list_comp=True) + + def visit_SetComp(self, node): + return self._process_comprehension(node) + + def visit_GeneratorExp(self, node): + return self._process_comprehension(node) + + def visit_ClassDef(self, node): + with self.state[_FunctionOrClass] as fn: + fn.node = node + # The ClassDef node itself has a Scope object that tracks the creation + # of its name, along with the usage of any decorator accompanying it. + self._enter_scope(False) + node.decorator_list = self.visit_block(node.decorator_list) + self.scope.modified.add(qual_names.QN(node.name)) + self.scope.bound.add(qual_names.QN(node.name)) + node.bases = self.visit_block(node.bases) + node.keywords = self.visit_block(node.keywords) + self._exit_and_record_scope(node) + + # A separate Scope tracks the actual class definition. + self._enter_scope(True) + node = self.generic_visit(node) + self._exit_scope() + return node + + def _visit_node_list(self, nodes): + return [(None if n is None else self.visit(n)) for n in nodes] + + def _visit_arg_annotations(self, node): + node.args.kw_defaults = self._visit_node_list(node.args.kw_defaults) + node.args.defaults = self._visit_node_list(node.args.defaults) + self._track_annotations_only = True + node = self._visit_arg_declarations(node) + self._track_annotations_only = False + return node + + def _visit_arg_declarations(self, node): + node.args.posonlyargs = self._visit_node_list(node.args.posonlyargs) + node.args.args = self._visit_node_list(node.args.args) + if node.args.vararg is not None: + node.args.vararg = self.visit(node.args.vararg) + node.args.kwonlyargs = self._visit_node_list(node.args.kwonlyargs) + if node.args.kwarg is not None: + node.args.kwarg = self.visit(node.args.kwarg) + return node + + def visit_FunctionDef(self, node): + with self.state[_FunctionOrClass] as fn: + fn.node = node + # The FunctionDef node itself has a Scope object that tracks the creation + # of its name, along with the usage of any decorator accompanying it. + self._enter_scope(False) + node.decorator_list = self.visit_block(node.decorator_list) + if node.returns: + node.returns = self._process_annotation(node.returns) + # Argument annotartions (including defaults) affect the defining context. + node = self._visit_arg_annotations(node) + + function_name = qual_names.QN(node.name) + self.scope.modified.add(function_name) + self.scope.bound.add(function_name) + self._exit_and_record_scope(node) + + # A separate Scope tracks the actual function definition. + self._enter_scope(True, node.name) + + # Keep a separate scope for the arguments node, which is used in the CFG. + self._enter_scope(False, node.name) + + # Arg declarations only affect the function itself, and have no effect + # in the defining context whatsoever. + node = self._visit_arg_declarations(node) + + self._exit_and_record_scope(node.args) + + # Track the body separately. This is for compatibility reasons, it may not + # be strictly needed. + self._enter_scope(False, node.name) + node.body = self.visit_block(node.body) + self._exit_and_record_scope(node, NodeAnno.BODY_SCOPE) + + self._exit_and_record_scope(node, NodeAnno.ARGS_AND_BODY_SCOPE) + return node + + def visit_Lambda(self, node): + # Lambda nodes are treated in roughly the same way as FunctionDef nodes. + with self.state[_FunctionOrClass] as fn: + fn.node = node + # The Lambda node itself has a Scope object that tracks the creation + # of its name, along with the usage of any decorator accompanying it. + self._enter_scope(False) + node = self._visit_arg_annotations(node) + self._exit_and_record_scope(node) + + # A separate Scope tracks the actual function definition. + self._enter_scope(True) + + # Keep a separate scope for the arguments node, which is used in the CFG. + self._enter_scope(False) + node = self._visit_arg_declarations(node) + self._exit_and_record_scope(node.args) + + # Track the body separately. This is for compatibility reasons, it may not + # be strictly needed. + # TODO(mdan): Do remove it, it's confusing. + self._enter_scope(False) + node.body = self.visit(node.body) + + # The lambda body can contain nodes of types normally not found as + # statements, and may not have the SCOPE annotation needed by the CFG. + # So we attach one if necessary. + if not anno.hasanno(node.body, anno.Static.SCOPE): + anno.setanno(node.body, anno.Static.SCOPE, self.scope) + + self._exit_and_record_scope(node, NodeAnno.BODY_SCOPE) + + lambda_scope = self.scope + self._exit_and_record_scope(node, NodeAnno.ARGS_AND_BODY_SCOPE) + + # TODO(bhack:) https://github.com/tensorflow/tensorflow/issues/56089 + # remove after deprecation + # Exception: lambdas are assumed to be used in the place where + # they are defined. Therefore, their activity is passed on to the + # calling statement. + self.scope.read.update(lambda_scope.read - lambda_scope.bound) + + return node + + def visit_With(self, node): + self._enter_scope(False) + node = self.generic_visit(node) + self._exit_and_record_scope(node, NodeAnno.BODY_SCOPE) + return node + + def visit_withitem(self, node): + return self._process_statement(node) + + def visit_If(self, node): + self._enter_scope(False) + node.test = self.visit(node.test) + node_scope = self._exit_and_record_scope(node.test) + anno.setanno(node, NodeAnno.COND_SCOPE, node_scope) + + node = self._process_parallel_blocks(node, + ((node.body, NodeAnno.BODY_SCOPE), + (node.orelse, NodeAnno.ORELSE_SCOPE))) + return node + + def visit_For(self, node): + self._enter_scope(False) + node.target = self.visit(node.target) + node.iter = self.visit(node.iter) + self._exit_and_record_scope(node.iter) + + self._enter_scope(False) + self.visit(node.target) + if anno.hasanno(node, anno.Basic.EXTRA_LOOP_TEST): + self._process_statement(anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST)) + self._exit_and_record_scope(node, tag=NodeAnno.ITERATE_SCOPE) + + node = self._process_parallel_blocks(node, + ((node.body, NodeAnno.BODY_SCOPE), + (node.orelse, NodeAnno.ORELSE_SCOPE))) + return node + + def visit_While(self, node): + self._enter_scope(False) + node.test = self.visit(node.test) + node_scope = self._exit_and_record_scope(node.test) + anno.setanno(node, NodeAnno.COND_SCOPE, node_scope) + + node = self._process_parallel_blocks(node, + ((node.body, NodeAnno.BODY_SCOPE), + (node.orelse, NodeAnno.ORELSE_SCOPE))) + return node + + def visit_ExceptHandler(self, node): + self._enter_scope(False) + # try/except oddity: as expected, it leaks any names you defined inside the + # except block, but not the name of the exception variable. + if node.name is not None: + self.scope.isolated_names.add(anno.getanno(node.name, anno.Basic.QN)) + node = self.generic_visit(node) + self._exit_scope() + return node + + +def resolve(node, context, parent_scope=None): + return ActivityAnalyzer(context, parent_scope).visit(node) diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/annos.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/annos.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85cc3d72253f3e3f141619e260a74c6954d1d --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/annos.py @@ -0,0 +1,55 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Annotations used by the static analyzer.""" + +from enum import Enum + + +# TODO(mdan): Remove. + + +class NoValue(Enum): + + def __repr__(self): # pylint: disable=invalid-repr-returned + return self.name + + +class NodeAnno(NoValue): + """Additional annotations used by the static analyzer. + + These are in addition to the basic annotations declared in anno.py. + """ + + # Symbols + # These flags are boolean. + IS_LOCAL = 'Symbol is local to the function scope being analyzed.' + IS_PARAM = 'Symbol is a parameter to the function being analyzed.' + IS_MODIFIED_SINCE_ENTRY = ( + 'Symbol has been explicitly replaced in the current function scope.') + + # Scopes + # Scopes are represented by objects of type activity.Scope. + ARGS_SCOPE = 'The scope for the argument list of a function call.' + COND_SCOPE = 'The scope for the test node of a conditional statement.' + ITERATE_SCOPE = 'The scope for the iterate assignment of a for loop.' + ARGS_AND_BODY_SCOPE = ( + 'The scope for the main body of a function or lambda, including its' + ' arguments.') + BODY_SCOPE = ( + 'The scope for the main body of a statement (True branch for if ' + 'statements, main body for loops).') + ORELSE_SCOPE = ( + 'The scope for the orelse body of a statement (False branch for if ' + 'statements, orelse body for loops).') diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py new file mode 100644 index 0000000000000000000000000000000000000000..6a1eae04998d57b3edcf728ac168addf6c3a5842 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py @@ -0,0 +1,220 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Live variable analysis. + +See https://en.wikipedia.org/wiki/Live_variable_analysis for a definition of +the following idioms: live variable, live in, live out, which are used +throughout this file. + +This analysis attaches the following: + * symbols that are live at the exit of control flow statements + * symbols that are live at the entry of control flow statements + +Requires activity analysis. +""" + +import gast + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import transformer +from tensorflow.python.autograph.pyct.static_analysis import annos + + +class Analyzer(cfg.GraphVisitor): + """CFG visitor that performs liveness analysis at statement level.""" + + def __init__(self, graph, include_annotations): + super(Analyzer, self).__init__(graph) + self.include_annotations = include_annotations + + def init_state(self, _): + return set() + + def lamba_check(self, fn_ast_node): + if isinstance(fn_ast_node, gast.Lambda): + # Exception: lambda functions are assumed to be used only in the + # place where they are defined, and not later. + return True + return False + + def visit_node(self, node): + prev_live_in = self.in_[node] + + if anno.hasanno(node.ast_node, anno.Static.SCOPE): + node_scope = anno.getanno(node.ast_node, anno.Static.SCOPE) + + gen = node_scope.read + if not self.include_annotations: + gen -= node_scope.annotations + # TODO(mdan): verify whether composites' parents need to be added. + # E.g. whether x needs to be added if x.y is live. Theoretically the + # activity analysis should have both so that wouldn't be needed. + kill = node_scope.modified | node_scope.deleted + + live_out = set() + for n in node.next: + live_out |= self.in_[n] + live_in = gen | (live_out - kill) + + reaching_functions = anno.getanno( + node.ast_node, anno.Static.DEFINED_FNS_IN) + for fn_ast_node in reaching_functions: + if self.lamba_check(fn_ast_node): + continue + fn_scope = anno.getanno(fn_ast_node, annos.NodeAnno.ARGS_AND_BODY_SCOPE) + # Any closure of a reaching function definition is conservatively + # considered live. + live_in |= (fn_scope.read - fn_scope.bound) + + else: + assert self.can_ignore(node), (node.ast_node, node) + + live_out = set() + for n in node.next: + live_out |= self.in_[n] + live_in = live_out + + self.in_[node] = live_in + self.out[node] = live_out + + # TODO(mdan): Move this to the superclass? + return prev_live_in != live_in + + +class TreeAnnotator(transformer.Base): + """Runs liveness analysis on each of the functions defined in the AST. + + If a function defined other local functions, those will have separate CFGs. + However, dataflow analysis needs to tie up these CFGs to properly emulate the + effect of closures. In the case of liveness, the parent function's live + variables must account for the variables that are live at the entry of each + subfunction. For example: + + def foo(): + # baz is live from here on + def bar(): + print(baz) + + This analyzer runs liveness analysis on each individual function, accounting + for the effect above. + """ + + def __init__(self, source_info, graphs, include_annotations): + super(TreeAnnotator, self).__init__(source_info) + self.include_annotations = include_annotations + self.allow_skips = False + self.graphs = graphs + self.current_analyzer = None + + def visit(self, node): + node = super(TreeAnnotator, self).visit(node) + if (self.current_analyzer is not None and + isinstance(node, gast.stmt) and + node in self.current_analyzer.graph.index): + cfg_node = self.current_analyzer.graph.index[node] + anno.setanno(node, anno.Static.LIVE_VARS_IN, + frozenset(self.current_analyzer.in_[cfg_node])) + return node + + def _analyze_function(self, node, is_lambda): + parent_analyzer = self.current_analyzer + + analyzer = Analyzer(self.graphs[node], self.include_annotations) + analyzer.visit_reverse() + self.current_analyzer = analyzer + node = self.generic_visit(node) + + self.current_analyzer = parent_analyzer + return node + + def visit_Lambda(self, node): + return self._analyze_function(node, is_lambda=True) + + def visit_FunctionDef(self, node): + return self._analyze_function(node, is_lambda=False) + + def _block_statement_live_out(self, node): + successors = self.current_analyzer.graph.stmt_next[node] + stmt_live_out = set() + for s in successors: + stmt_live_out.update(self.current_analyzer.in_[s]) + anno.setanno(node, anno.Static.LIVE_VARS_OUT, frozenset(stmt_live_out)) + return node + + def _block_statement_live_in(self, node, entry_node): + if entry_node in self.current_analyzer.graph.index: + cfg_node = self.current_analyzer.graph.index[entry_node] + stmt_live_in = frozenset(self.current_analyzer.in_[cfg_node]) + else: + assert anno.hasanno(entry_node, anno.Static.LIVE_VARS_IN), ( + 'If not matching a CFG node, must be a block statement:' + ' {}'.format(entry_node)) + stmt_live_in = anno.getanno(entry_node, anno.Static.LIVE_VARS_IN) + anno.setanno(node, anno.Static.LIVE_VARS_IN, stmt_live_in) + return node + + def visit_If(self, node): + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.test) + + def visit_For(self, node): + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.iter) + + def visit_While(self, node): + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.test) + + def visit_Try(self, node): + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.body[0]) + + def visit_ExceptHandler(self, node): + node = self.generic_visit(node) + node = self._block_statement_live_out(node) + return self._block_statement_live_in(node, node.body[0]) + + def visit_With(self, node): + node = self.generic_visit(node) + return self._block_statement_live_in(node, node.items[0]) + + def visit_Expr(self, node): + node = self.generic_visit(node) + cfg_node = self.current_analyzer.graph.index[node] + anno.setanno(node, anno.Static.LIVE_VARS_OUT, + frozenset(self.current_analyzer.out[cfg_node])) + return node + + +# TODO(mdan): Investigate the possibility of removing include_annotations. +def resolve(node, source_info, graphs, include_annotations=True): + """Resolves the live symbols at the exit of control flow statements. + + Args: + node: ast.AST + source_info: transformer.SourceInfo + graphs: Dict[ast.FunctionDef, cfg.Graph] + include_annotations: Bool, whether type annotations should be included in + the analysis. + Returns: + ast.AST + """ + node = TreeAnnotator(source_info, graphs, include_annotations).visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_definitions.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_definitions.py new file mode 100644 index 0000000000000000000000000000000000000000..aa07142528ee0129b99fe6f49ffc189ca9bcea58 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_definitions.py @@ -0,0 +1,288 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Reaching definition analysis. + +This analysis attaches a set of a Definition objects to each symbol, one +for each distinct definition that may reach it. The Definition objects are +mutable and may be used by subsequent analyses to further annotate data like +static type and value information. +The analysis also attaches the set of the symbols defined at the entry of +control flow statements. + +Requires activity analysis. +""" + +import weakref + +import gast + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import transformer + + +class Definition(object): + """Definition objects describe a unique definition of a variable. + + Subclasses of this may be used by passing an appropriate factory function to + resolve. + + Attributes: + param_of: Optional[ast.AST] + directives: Dict, optional definition annotations + """ + + def __init__(self): + self.param_of = None + self.directives = {} + + def __repr__(self): + return '%s[%d]' % (self.__class__.__name__, id(self)) + + +class _NodeState(object): + """Abstraction for the state of the CFG walk for reaching definition analysis. + + This is a value type. Only implements the strictly necessary operators. + + Attributes: + value: Dict[qual_names.QN, Set[Definition, ...]], the defined symbols and + their possible definitions + """ + + def __init__(self, init_from=None): + if init_from: + if isinstance(init_from, _NodeState): + self.value = { + s: set(other_infos) for s, other_infos in init_from.value.items() + } + elif isinstance(init_from, dict): + self.value = {s: set((init_from[s],)) for s in init_from} + else: + assert False, init_from + else: + self.value = {} + + def __eq__(self, other): + if frozenset(self.value.keys()) != frozenset(other.value.keys()): + return False + ret = all(self.value[s] == other.value[s] for s in self.value) + return ret + + def __ne__(self, other): + return not self.__eq__(other) + + def __or__(self, other): + assert isinstance(other, _NodeState) + result = _NodeState(self) + for s, other_infos in other.value.items(): + if s in result.value: + result.value[s].update(other_infos) + else: + result.value[s] = set(other_infos) + return result + + def __sub__(self, other): + assert isinstance(other, set) + result = _NodeState(self) + for s in other: + result.value.pop(s, None) + return result + + def __repr__(self): + return 'NodeState[%s]=%s' % (id(self), repr(self.value)) + + +class Analyzer(cfg.GraphVisitor): + """CFG visitor that determines reaching definitions at statement level.""" + + def __init__(self, graph, definition_factory): + self._definition_factory = definition_factory + super(Analyzer, self).__init__(graph) + self.gen_map = {} + + def init_state(self, _): + return _NodeState() + + def visit_node(self, node): + prev_defs_out = self.out[node] + + defs_in = _NodeState() + for n in node.prev: + defs_in |= self.out[n] + + if anno.hasanno(node.ast_node, anno.Static.SCOPE): + node_scope = anno.getanno(node.ast_node, anno.Static.SCOPE) + # The definition objects created by each node must be singletons because + # their ids are used in equality checks. + if node not in self.gen_map: + node_symbols = {} + # Every binding operation (assign, nonlocal, global, etc.) counts as a + # definition, with the exception of del, which only deletes without + # creating a new variable. + newly_defined = ((node_scope.bound | node_scope.globals) - + node_scope.deleted) + for s in newly_defined: + def_ = self._definition_factory() + node_symbols[s] = def_ + # Every param receives a definition. Params are not necessarily + # considered as "modified". + for s, p in node_scope.params.items(): + def_ = self._definition_factory() + def_.param_of = weakref.ref(p) + node_symbols[s] = def_ + self.gen_map[node] = _NodeState(node_symbols) + + gen = self.gen_map[node] + kill = node_scope.modified | node_scope.deleted + defs_out = gen | (defs_in - kill) + + gen = self.gen_map[node] + defs_out = gen | (defs_in - kill) + + else: + assert self.can_ignore(node), (node.ast_node, node) + defs_out = defs_in + + self.in_[node] = defs_in + self.out[node] = defs_out + + return prev_defs_out != defs_out + + +class TreeAnnotator(transformer.Base): + """AST visitor that annotates each symbol name with its reaching definitions. + + Simultaneously, the visitor runs the dataflow analysis on each function node, + accounting for the effect of closures. For example: + + def foo(): + bar = 1 + def baz(): + # bar = 1 reaches here + """ + + def __init__(self, source_info, graphs, definition_factory): + super(TreeAnnotator, self).__init__(source_info) + self.allow_skips = False + self.definition_factory = definition_factory + self.graphs = graphs + self.current_analyzer = None + self.current_cfg_node = None + + def visit_FunctionDef(self, node): + parent_analyzer = self.current_analyzer + subgraph = self.graphs[node] + + analyzer = Analyzer(subgraph, self.definition_factory) + analyzer.visit_forward() + + # Recursively process any remaining subfunctions. + self.current_analyzer = analyzer + node.args = self.visit(node.args) + node.body = self.visit_block(node.body) + self.current_analyzer = parent_analyzer + + return node + + def visit_Name(self, node): + if self.current_analyzer is None: + # Names may appear outside function defs - for example in class + # definitions. + return node + + analyzer = self.current_analyzer + cfg_node = self.current_cfg_node + + assert cfg_node is not None, ('name node, %s, outside of any statement?' + % node.id) + + qn = anno.getanno(node, anno.Basic.QN) + if isinstance(node.ctx, gast.Load): + anno.setanno(node, anno.Static.DEFINITIONS, + tuple(analyzer.in_[cfg_node].value.get(qn, ()))) + else: + anno.setanno(node, anno.Static.DEFINITIONS, + tuple(analyzer.out[cfg_node].value.get(qn, ()))) + + return node + + def _aggregate_predecessors_defined_in(self, node): + preds = self.current_analyzer.graph.stmt_prev[node] + node_defined_in = set() + for p in preds: + node_defined_in |= set(self.current_analyzer.out[p].value.keys()) + anno.setanno(node, anno.Static.DEFINED_VARS_IN, frozenset(node_defined_in)) + + def visit_If(self, node): + self._aggregate_predecessors_defined_in(node) + return self.generic_visit(node) + + def visit_For(self, node): + self._aggregate_predecessors_defined_in(node) + + # Manually accounting for the shortcoming described in + # cfg.AstToCfg.visit_For. + parent = self.current_cfg_node + self.current_cfg_node = self.current_analyzer.graph.index[node.iter] + node.target = self.visit(node.target) + self.current_cfg_node = parent + + node.iter = self.visit(node.iter) + node.body = self.visit_block(node.body) + node.orelse = self.visit_block(node.orelse) + + return node + + def visit_While(self, node): + self._aggregate_predecessors_defined_in(node) + return self.generic_visit(node) + + def visit_Try(self, node): + self._aggregate_predecessors_defined_in(node) + return self.generic_visit(node) + + def visit_ExceptHandler(self, node): + self._aggregate_predecessors_defined_in(node) + # TODO(mdan): Also track the exception type / name symbols. + node.body = self.visit_block(node.body) + return node + + def visit(self, node): + parent = self.current_cfg_node + + if (self.current_analyzer is not None and + node in self.current_analyzer.graph.index): + self.current_cfg_node = self.current_analyzer.graph.index[node] + node = super(TreeAnnotator, self).visit(node) + + self.current_cfg_node = parent + return node + + +def resolve(node, source_info, graphs, definition_factory=Definition): + """Resolves reaching definitions for each symbol. + + Args: + node: ast.AST + source_info: transformer.SourceInfo + graphs: Dict[ast.FunctionDef, cfg.Graph] + definition_factory: Callable[[], Definition] + Returns: + ast.AST + """ + visitor = TreeAnnotator(source_info, graphs, definition_factory) + node = visitor.visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_fndefs.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_fndefs.py new file mode 100644 index 0000000000000000000000000000000000000000..2ef592edf5f13a353a7dc1d42962d21927a28ea7 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/reaching_fndefs.py @@ -0,0 +1,178 @@ +# Copyright 2018 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""An analysis that determines the reach of a function definition. + +A function definition is said to reach a statement if that function may exist +(and therefore may be called) when that statement executes. +""" + +import gast + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import transformer + + +class Definition(object): + """Definition objects describe a unique definition of a function.""" + + def __init__(self, def_node): + self.def_node = def_node + + +class _NodeState(object): + """Abstraction for the state of the CFG walk for reaching definition analysis. + + This is a value type. Only implements the strictly necessary operators. + + Attributes: + value: Dict[qual_names.QN, Set[Definition, ...]], the defined symbols and + their possible definitions + """ + + def __init__(self, init_from=None): + if init_from: + self.value = set(init_from) + else: + self.value = set() + + def __eq__(self, other): + return self.value == other.value + + def __ne__(self, other): + return self.value != other.value + + def __or__(self, other): + assert isinstance(other, _NodeState) + result = _NodeState(self.value) + result.value.update(other.value) + return result + + def __add__(self, value): + result = _NodeState(self.value) + result.value.add(value) + return result + + def __repr__(self): + return 'NodeState[%s]=%s' % (id(self), repr(self.value)) + + +class Analyzer(cfg.GraphVisitor): + """CFG visitor that determines reaching definitions at statement level.""" + + def __init__(self, graph, external_defs): + super(Analyzer, self).__init__(graph) + # This allows communicating that nodes have extra reaching definitions, + # e.g. those that a function closes over. + self.external_defs = external_defs + + def init_state(self, _): + return _NodeState() + + def visit_node(self, node): + prev_defs_out = self.out[node] + + if node is self.graph.entry: + defs_in = _NodeState(self.external_defs) + else: + defs_in = prev_defs_out + + for n in node.prev: + defs_in |= self.out[n] + + defs_out = defs_in + if isinstance(node.ast_node, (gast.Lambda, gast.FunctionDef)): + defs_out += node.ast_node + + self.in_[node] = defs_in + self.out[node] = defs_out + + return prev_defs_out != defs_out + + +class TreeAnnotator(transformer.Base): + """AST visitor that annotates each symbol name with its reaching definitions. + + Simultaneously, the visitor runs the dataflow analysis on each function node, + accounting for the effect of closures. For example: + + def foo(): + def f(): + pass + def g(): + # `def f` reaches here + """ + + def __init__(self, source_info, graphs): + super(TreeAnnotator, self).__init__(source_info) + self.graphs = graphs + self.allow_skips = False + self.current_analyzer = None + + def _proces_function(self, node): + parent_analyzer = self.current_analyzer + subgraph = self.graphs[node] + + if (self.current_analyzer is not None + and node in self.current_analyzer.graph.index): + cfg_node = self.current_analyzer.graph.index[node] + defined_in = self.current_analyzer.in_[cfg_node].value + else: + defined_in = () + + analyzer = Analyzer(subgraph, defined_in) + analyzer.visit_forward() + + self.current_analyzer = analyzer + node = self.generic_visit(node) + self.current_analyzer = parent_analyzer + return node + + def visit_FunctionDef(self, node): + return self._proces_function(node) + + def visit_Lambda(self, node): + return self._proces_function(node) + + def visit(self, node): + # This can happen before entering the top level function + if (self.current_analyzer is not None + and node in self.current_analyzer.graph.index): + cfg_node = self.current_analyzer.graph.index[node] + anno.setanno(node, anno.Static.DEFINED_FNS_IN, + self.current_analyzer.in_[cfg_node].value) + + extra_node = anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST, default=None) + if extra_node is not None: + cfg_node = self.current_analyzer.graph.index[extra_node] + anno.setanno(extra_node, anno.Static.DEFINED_FNS_IN, + self.current_analyzer.in_[cfg_node].value) + + return super(TreeAnnotator, self).visit(node) + + +def resolve(node, source_info, graphs): + """Resolves reaching definitions for each symbol. + + Args: + node: ast.AST + source_info: transformer.SourceInfo + graphs: Dict[ast.FunctionDef, cfg.Graph] + Returns: + ast.AST + """ + visitor = TreeAnnotator(source_info, graphs) + node = visitor.visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/type_inference.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/type_inference.py new file mode 100644 index 0000000000000000000000000000000000000000..d5ab1f5c541ce94a8786af2ef1c58ec10c0701e8 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/static_analysis/type_inference.py @@ -0,0 +1,625 @@ +# Copyright 2020 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Type inference. + +This analysis annotates all symbols nodes of an AST with type information +extracted from static sources: + * type annotations + * global and local symbols visible to the function at analysis time + * literals + +Important: This analysis is static, and does not detect dynamic type changes. +The analysis attempts to use the values of external symbols, if available. These +values are also considered static for the purpose of analysis. + +Requires reaching function definitions analysis. +""" + +import itertools + +from typing import Any, Callable, Dict, Set + +import gast + +from tensorflow.python.autograph.pyct import anno +from tensorflow.python.autograph.pyct import cfg +from tensorflow.python.autograph.pyct import qual_names +from tensorflow.python.autograph.pyct import transformer +from tensorflow.python.autograph.pyct.static_analysis import activity +from tensorflow.python.autograph.pyct.static_analysis import annos + + +class Resolver(object): + """Resolver objects handle the process of looking up actual names and types. + + Unless noted otherwise, all resolve_* methods: + * have a first namespace argument, mapping string to actual values + * have a second types_namespace argument, mapping string to actual inferred + types + * specify names as QN objects + * specify types as a Set of inferred types + + Unless noted otherwise, all resolve_* methods must return either: + * a set of `type` objects + * None + """ + + def res_name(self, ns, types_ns, name): + """Resolves the type/value an external (e.g. closure, global) variable. + + Args: + ns: namespace + types_ns: types namespace + name: symbol name + + Returns: + Tuple (type, static_value). The first element is the type to use for + inference. The second is the static value to use. Return None to treat it + as unknown. + """ + raise NotImplementedError('subclasses must implement') + + def res_value(self, ns, value): + """Resolves the type a literal or static value.""" + raise NotImplementedError('subclasses must implement') + + def res_arg(self, ns, types_ns, f_name, name, type_anno, f_is_local): + """Resolves the type of a (possibly annotated) function argument. + + Args: + ns: namespace + types_ns: types namespace + f_name: str, the function name + name: str, the argument name + type_anno: the type annotating the argument, if any + f_is_local: bool, whether the function is a local function + Returns: + Set of the argument types. + """ + raise NotImplementedError('subclasses must implement') + + def res_call(self, ns, types_ns, node, f_type, args, keywords): + """Resolves the return type an external function or method call. + + Args: + ns: namespace + types_ns: types namespace + node: str, the function name + f_type: types of the actual function being called, if known + args: types of each respective argument in node.args + keywords: types of each respective argument in node.keywords + + Returns: + Tuple (return_type, side_effect_types). The first element is just the + return types of the function. The second element is a map from + argument names to sets of types, and allow modelling side effects of + functions (for example via global or nonlocal). + """ + raise NotImplementedError('subclasses must implement') + + # TODO(mdan): Clean this up. + def res_slice(self, ns, types_ns, node_or_slice, value, slice_): + """Resolves the return type of slice operation.""" + raise NotImplementedError('subclasses must implement') + + def res_compare(self, ns, types_ns, node, left, right): + """Resolves the return type of a unary operation.""" + raise NotImplementedError('subclasses must implement') + + def res_unop(self, ns, types_ns, node, opnd): + """Resolves the return type of a unary operation.""" + raise NotImplementedError('subclasses must implement') + + def res_binop(self, ns, types_ns, node, left, right): + """Resolves the return type of a binary operation.""" + raise NotImplementedError('subclasses must implement') + + def res_list_literal(self, ns, elt_types): + """Resolves the type of a list literal from its elements.""" + raise NotImplementedError('subclasses must implement') + + +class _TypeMap(object): + """Abstraction for the state of the CFG walk for type inference. + + This is a value type. Only implements the strictly necessary operators. + + Attributes: + types: Dict[qual_names.QN, Set[Type]], mapping symbols to the set of + possible types. + """ + + def __init__(self, init_from=None): + if init_from: + assert isinstance(init_from, _TypeMap) + self.types = { + s: set(other_types) for s, other_types in init_from.types.items() + } + else: + self.types = {} + + def __eq__(self, other): + if frozenset(self.types.keys()) != frozenset(other.types.keys()): + return False + ret = all(self.types[s] == other.types[s] for s in self.types) + return ret + + def __ne__(self, other): + return not self.__eq__(other) + + def __or__(self, other): + assert isinstance(other, _TypeMap) + result = _TypeMap(self) + for s, other_types in other.types.items(): + if s not in result.types: + self_types = set() + result.types[s] = self_types + else: + self_types = result.types[s] + self_types.update(other_types) + return result + + def __repr__(self): + return 'SymbolTable {}'.format(self.types) + + +NO_VALUE = object() + + +class StmtInferrer(gast.NodeVisitor): + """Runs type inference on a single AST statement. + + This visitor annotates most nodes with type information. It also sets types + for the symbols modified by this statement in its types_out property. + + Note: this inferrer is able to capture side effects of functions, however, + these side effects will not be applied to the current expression. Doing so + would create too much of a dependence on the runtime's internal rules about + execution order. + Example: + + def f(): + nonlocal a + a = 1 + return a + + a = 0.0 + b = f() + a # a = float; side effect of f() ignored + print(a) # a = int; side effect of f() accounted for + """ + + def __init__(self, + resolver: Resolver, + scope: activity.Scope, + namespace: Dict[qual_names.QN, Any], + closure_types: Dict[qual_names.QN, Set[Any]], + types_in: _TypeMap): + self.resolver = resolver + self.scope = scope + self.namespace = namespace + self.closure_types = closure_types + self.types_in = types_in + self.new_symbols = {} + + # rvalue type. This property is set when encountering an assign operation, + # so that visiting nodes with Store ctx (typically found on left side of + # assignments) can infer the type they should receive. + self.rtype = None + + def visit(self, node): + types = super().visit(node) + if __debug__: + self._check_set(types) + if types is not None: + # TODO(mdan): Normalize by removing subtypes. + anno.setanno(node, anno.Static.TYPES, tuple(types)) + return types + + def _check_set(self, value): + if value is not None and not isinstance(value, set): + raise ValueError('{} method expected to return set, got {}'.format( + self.resolver, value)) + + def visit_Constant(self, node): + types = self.resolver.res_value(self.namespace, node.value) + if __debug__: + self._check_set(types) + return types + + def _apply_unpacking(self, node): + assert isinstance(node.ctx, gast.Store) + if self.rtype is not None: + original_stype = self.rtype + # TODO(mdan): Find a better way to express unpacking. + i_type = self.resolver.res_value(self.namespace, 0) + for i, elt in enumerate(node.elts): + self.rtype = self.resolver.res_slice( + self.namespace, self.types_in.types, i, original_stype, i_type) + self.visit(elt) + self.rtype = original_stype + return original_stype + return None + + def visit_Tuple(self, node): + if isinstance(node.ctx, gast.Load): + elt_types = () + for elt in node.elts: + types_ = self.visit(elt) + if types_ is None: + return None + elt_types += (types_,) + return set(itertools.product(*elt_types)) + return self._apply_unpacking(node) + + def visit_List(self, node): + if isinstance(node.ctx, gast.Load): + elt_types = tuple(self.visit(elt) for elt in node.elts) + return self.resolver.res_list_literal(self.namespace, elt_types) + return self._apply_unpacking(node) + + def visit_Set(self, node): + raise NotImplementedError() + + def visit_Name(self, node): + name = anno.getanno(node, anno.Basic.QN) + + if isinstance(node.ctx, gast.Load): + types = self.types_in.types.get(name, None) + if types is None: + if (name not in self.scope.bound) or (name in self.scope.nonlocals): + # TODO(mdan): Test with global variables. + if name in self.closure_types: + types = self.closure_types[name] + else: + types, value = self.resolver.res_name( + self.namespace, self.types_in.types, name) + if value is not None: + anno.setanno(node, anno.Static.VALUE, value) + + elif isinstance(node.ctx, gast.Param): + # The direct parent it the whole function scope. See activity.py. + f_is_local = self.scope.parent.parent is not None + + type_name = anno.getanno(node.annotation, anno.Basic.QN, None) + types = self.resolver.res_arg(self.namespace, self.types_in.types, + self.scope.function_name, name, type_name, + f_is_local) + if types is not None: + self.new_symbols[name] = types + + elif isinstance(node.ctx, gast.Store): + if self.rtype is not None: + self.new_symbols[name] = self.rtype + types = self.rtype + + else: + assert False, 'unknown ctx' + + if __debug__: + self._check_set(types) + + return types + + def visit_Attribute(self, node): + parent_types = self.visit(node.value) + + # Attempt to use the static value if known. + parent_value = anno.Static.VALUE.of(node.value, None) + if parent_value is not None: + static_value = getattr(parent_value, node.attr, NO_VALUE) + + if static_value is NO_VALUE: + # Unexpected failure to resolve attribute. Ask the resolver about the + # full name instead. + types, static_value = self.resolver.res_name( + self.namespace, self.types_in, anno.Basic.QN.of(node)) + anno.setanno(node, anno.Static.VALUE, static_value) + if __debug__: + self._check_set(types) + return types + + else: + # Fall back to the type if that is known. + if parent_types is None: + return None + + inferred_values = [getattr(t, node.attr, None) for t in parent_types] + if not inferred_values: + return None + + static_value = inferred_values[0] + if static_value is None: + return None + + if any(v is not static_value for v in inferred_values[1:]): + # Static value not stable, assume it's dynamic. + return None + + types = self.resolver.res_value(self.namespace, static_value) + anno.setanno(node, anno.Static.VALUE, static_value) + + if __debug__: + self._check_set(types) + + return types + + def visit_FunctionDef(self, node): + f_name = qual_names.QN(node.name) + + if node.decorator_list: + raise NotImplementedError('decorators: {}'.format(node.decorator_list)) + + ret_types = None + if node.returns: + ret_types, _ = self.resolver.res_name( + self.namespace, self.types_in.types, anno.Basic.QN.of(node.returns)) + if __debug__: + self._check_set(ret_types) + + if ret_types is None: + ret_types = {Any} + + f_types = set() + for rt in ret_types: + f_types.add(Callable[[Any], rt]) + + self.new_symbols[f_name] = f_types + # The definition of a function is an expression, hence has no return value. + return None + + def _resolve_typed_callable(self, f_types, arg_types, keyword_types): + ret_types = set() + for t in f_types: + + if isinstance(t, Callable): + # Note: these are undocumented - may be version-specific! + # Callable[[x], y]: __args__ are (x, y) + args = t.__args__ + if args: + ret_types.add(args[-1]) + else: + ret_types.add(Any) + else: + raise NotImplementedError('callable type {}'.format(type(t))) + + # Side effects can not be inferred based on type alone. + side_effects = None + return ret_types, side_effects + + def visit_Call(self, node): + self.visit(node.func) + + f_name = anno.Basic.QN.of(node.func) + arg_types = [self.visit(a) for a in node.args] + keyword_types = [self.visit(kw.value) for kw in node.keywords] + + if f_name in self.scope.bound: + # Local function, use local type definitions, if available. + f_type = self.types_in.types.get(f_name, None) + if f_type is None: + # No static type info available, nothing more to do. + ret_type, side_effects = None, None + else: + ret_type, side_effects = self._resolve_typed_callable( + f_type, arg_types, keyword_types) + + else: + # Nonlocal function, resolve externally. + f_type = anno.Static.TYPES.of(node.func, None) + ret_type, side_effects = self.resolver.res_call(self.namespace, + self.types_in.types, node, + f_type, arg_types, + keyword_types) + + if __debug__: + self._check_set(ret_type) + if side_effects: + if not isinstance(side_effects, dict): + raise ValueError( + 'side effects must be dict, got {}'.format(side_effects)) + for k, v in side_effects.items(): + if not isinstance(k, qual_names.QN): + raise ValueError('side effect keys must be QNs, got {}'.format(k)) + self._check_set(v) + + if side_effects: + self.new_symbols.update(side_effects) + return ret_type + + def visit_Expr(self, node): + return self.visit(node.value) + + def visit_Assign(self, node): + self.rtype = self.visit(node.value) + + for t in node.targets: + self.visit(t) + + self.rtype = None + + def visit_Subscript(self, node): + val_types = self.visit(node.value) + slice_types = self.visit(node.slice) + + if val_types is None or slice_types is None: + return None + + types = self.resolver.res_slice( + self.namespace, self.types_in.types, node, val_types, slice_types) + + if __debug__: + self._check_set(types) + + return types + + def visit_Compare(self, node): + left_types = self.visit(node.left) + right_types = [self.visit(c) for c in node.comparators] + + if left_types is None or any(t is None for t in right_types): + return None + + types = self.resolver.res_compare( + self.namespace, self.types_in.types, node, left_types, right_types) + + if __debug__: + self._check_set(types) + + return types + + def visit_BinOp(self, node): + left_types = self.visit(node.left) + right_types = self.visit(node.right) + + if left_types is None or right_types is None: + return None + + types = self.resolver.res_binop( + self.namespace, self.types_in.types, node, left_types, right_types) + + if __debug__: + self._check_set(types) + + return types + + def visit_UnaryOp(self, node): + opnd_types = self.visit(node.operand) + + if opnd_types is None: + return None + + types = self.resolver.res_unop( + self.namespace, self.types_in.types, node, opnd_types) + + if __debug__: + self._check_set(types) + + return types + + +class Analyzer(cfg.GraphVisitor): + """CFG visitor that propagates type information across statements.""" + + def __init__(self, graph, resolver, namespace, scope, closure_types): + """Creates a new analyzer. + + Args: + graph: cfg.Graph + resolver: Resolver + namespace: Dict[str, Any] + scope: activity.Scope + closure_types: Dict[QN, Set] + """ + super(Analyzer, self).__init__(graph) + self.resolver = resolver + self.namespace = namespace + self.scope = scope + self.closure_types = closure_types + + context_types = { + n: t for n, t in closure_types.items() if n not in scope.bound + } + if context_types: + self.context_types = _TypeMap() + self.context_types.types = context_types + else: + self.context_types = None + + def init_state(self, _): + return _TypeMap() + + def _update_closure_types(self, ast_node, types): + existing_types = anno.Static.CLOSURE_TYPES.of(ast_node, None) + + if existing_types is None: + existing_types = {} + anno.Static.CLOSURE_TYPES.add_to(ast_node, existing_types) + + for k, v in types.types.items(): + if k in existing_types: + existing_types[k].update(v) + else: + existing_types[k] = set(v) + + def visit_node(self, node): + prev_types_out = self.out[node] + + types_in = _TypeMap() + for n in node.prev: + types_in |= self.out[n] + if (self.context_types is not None) and (node is self.graph.entry): + types_in |= self.context_types + + types_out = _TypeMap(types_in) + ast_node = node.ast_node + + inferrer = StmtInferrer(self.resolver, self.scope, self.namespace, + self.closure_types, types_in) + inferrer.visit(ast_node) + types_out.types.update(inferrer.new_symbols) + + reaching_fndefs = anno.Static.DEFINED_FNS_IN.of(ast_node) + node_scope = anno.Static.SCOPE.of(ast_node, None) + if node_scope is not None: + # TODO(mdan): Check that it's actually safe to skip nodes without scope. + reads = {str(qn) for qn in node_scope.read} + for def_node in reaching_fndefs: + if def_node.name in reads: + self._update_closure_types(def_node, types_out) + + self.in_[node] = types_in + self.out[node] = types_out + + return prev_types_out != types_out + + +class FunctionVisitor(transformer.Base): + """AST visitor that applies type inference to each function separately.""" + + def __init__(self, source_info, graphs, resolver): + super(FunctionVisitor, self).__init__(source_info) + self.graphs = graphs + self.resolver = resolver + + def visit_FunctionDef(self, node): + subgraph = self.graphs[node] + scope = anno.getanno(node, annos.NodeAnno.ARGS_AND_BODY_SCOPE) + closure_types = anno.getanno(node, anno.Static.CLOSURE_TYPES, {}) + + analyzer = Analyzer(subgraph, self.resolver, self.ctx.info.namespace, scope, + closure_types) + analyzer.visit_forward() + + # Recursively process any remaining subfunctions. + node.body = self.visit_block(node.body) + + return node + + +def resolve(node, source_info, graphs, resolver): + """Performs type inference. + + Args: + node: ast.AST + source_info: transformer.SourceInfo + graphs: Dict[ast.FunctionDef, cfg.Graph] + resolver: Resolver + + Returns: + ast.AST + """ + visitor = FunctionVisitor(source_info, graphs, resolver) + node = visitor.visit(node) + return node diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__init__.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/__init__.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aed7f2dd0cab314fe80d4a587b7ab2b79457c82b Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/__init__.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/basic_definitions.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/basic_definitions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0678b44a337769b8dc12796d6407cc0591ea02a9 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/basic_definitions.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/decorators.cpython-310.pyc b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/decorators.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bafa935db505d7e460d47aadd9649d4ce92a8c22 Binary files /dev/null and b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/__pycache__/decorators.cpython-310.pyc differ diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/basic_definitions.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/basic_definitions.py new file mode 100644 index 0000000000000000000000000000000000000000..333b56ee889acfea889c11d55da2480938cd5b0d --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/basic_definitions.py @@ -0,0 +1,65 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Module with basic entity definitions for testing.""" + + +def simple_function(x): + """Docstring.""" + return x # comment + + +def nested_functions(x): + """Docstring.""" + + def inner_fn(y): + return y + + return inner_fn(x) + + +def function_with_print(): + print('foo') + + +simple_lambda = lambda: None + + +class SimpleClass(object): + + def simple_method(self): + return self + + def method_with_print(self): + print('foo') + + +def function_with_multiline_call(x): + """Docstring.""" + return range( + x, + x + 1, + ) + + +def basic_decorator(f): + return f + + +@basic_decorator +@basic_decorator +def decorated_function(x): + if x > 0: + return 1 + return 2 diff --git a/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/decorators.py b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/decorators.py new file mode 100644 index 0000000000000000000000000000000000000000..332686aed472fc7a45c5879c226d51385bc90403 --- /dev/null +++ b/SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/pyct/testing/decorators.py @@ -0,0 +1,46 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Module with test decorators.""" + +import functools + + +def wrapping_decorator(f): + + @functools.wraps(f) + def wrapper(*args, **kwargs): + return f(*args, **kwargs) + + return wrapper + + +def standalone_decorator(f): + + def standalone_wrapper(*args, **kwargs): + return f(*args, **kwargs) + + return standalone_wrapper + + +def functional_decorator(): + + def decorator(f): + + def functional_wrapper(*args, **kwargs): + return f(*args, **kwargs) + + return functional_wrapper + + return decorator