Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__init__.py +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/__init__.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/asserts.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/break_statements.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/call_trees.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/conditional_expressions.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/continue_statements.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/control_flow.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/directives.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/functions.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/lists.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/logical_expressions.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/return_statements.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/slices.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/variables.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/asserts.py +48 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/break_statements.py +185 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/call_trees.py +221 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/conditional_expressions.py +46 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/continue_statements.py +164 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/control_flow.py +413 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/directives.py +177 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/functions.py +134 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/lists.py +239 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/logical_expressions.py +131 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/return_statements.py +402 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/slices.py +83 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/variables.py +97 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__init__.py +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/__init__.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/ag_ctx.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config_lib.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter_testing.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/function_wrappers.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/unsupported_features_checker.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/ag_ctx.py +105 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config.py +62 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config_lib.py +61 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter.py +316 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter_testing.py +126 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/function_wrappers.py +113 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/unsupported_features_checker.py +57 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__init__.py +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/__init__.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/api.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/conversion.cpython-310.pyc +0 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/api.py +949 -0
- SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/conversion.py +227 -0
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__init__.py
ADDED
|
File without changes
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (214 Bytes). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/asserts.cpython-310.pyc
ADDED
|
Binary file (1.31 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/break_statements.cpython-310.pyc
ADDED
|
Binary file (4.22 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/call_trees.cpython-310.pyc
ADDED
|
Binary file (6.1 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/conditional_expressions.cpython-310.pyc
ADDED
|
Binary file (1.39 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/continue_statements.cpython-310.pyc
ADDED
|
Binary file (5.44 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/control_flow.cpython-310.pyc
ADDED
|
Binary file (11.8 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/directives.cpython-310.pyc
ADDED
|
Binary file (6.08 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/functions.cpython-310.pyc
ADDED
|
Binary file (3.49 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/lists.cpython-310.pyc
ADDED
|
Binary file (5.87 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/logical_expressions.cpython-310.pyc
ADDED
|
Binary file (3.61 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/return_statements.cpython-310.pyc
ADDED
|
Binary file (10.7 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/slices.cpython-310.pyc
ADDED
|
Binary file (2.32 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/__pycache__/variables.cpython-310.pyc
ADDED
|
Binary file (2.59 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/asserts.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converts assert statements to their corresponding TF calls."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import templates
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class AssertTransformer(converter.Base):
|
| 24 |
+
"""Transforms Assert nodes to Call so they can be handled as functions."""
|
| 25 |
+
|
| 26 |
+
def visit_Assert(self, node):
|
| 27 |
+
self.generic_visit(node)
|
| 28 |
+
|
| 29 |
+
# Note: The lone tf.Assert call will be wrapped with control_dependencies
|
| 30 |
+
# by side_effect_guards.
|
| 31 |
+
template = """
|
| 32 |
+
ag__.assert_stmt(test, lambda: msg)
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
if node.msg is None:
|
| 36 |
+
return templates.replace(
|
| 37 |
+
template,
|
| 38 |
+
test=node.test,
|
| 39 |
+
msg=gast.Constant('Assertion error', kind=None))
|
| 40 |
+
elif isinstance(node.msg, gast.Constant):
|
| 41 |
+
return templates.replace(template, test=node.test, msg=node.msg)
|
| 42 |
+
else:
|
| 43 |
+
raise NotImplementedError('can only convert string messages for now.')
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def transform(node, ctx):
|
| 47 |
+
node = AssertTransformer(ctx).visit(node)
|
| 48 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/break_statements.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Lowers break statements to conditionals."""
|
| 16 |
+
|
| 17 |
+
from tensorflow.python.autograph.core import converter
|
| 18 |
+
from tensorflow.python.autograph.pyct import anno
|
| 19 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 20 |
+
from tensorflow.python.autograph.pyct import templates
|
| 21 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 22 |
+
from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class _Break(object):
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self.used = False
|
| 29 |
+
self.control_var_name = None
|
| 30 |
+
|
| 31 |
+
def __repr__(self):
|
| 32 |
+
return 'used: %s, var: %s' % (self.used, self.control_var_name)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class BreakTransformer(converter.Base):
|
| 36 |
+
"""Canonicalizes break statements into additional conditionals."""
|
| 37 |
+
|
| 38 |
+
def visit_Break(self, node):
|
| 39 |
+
self.state[_Break].used = True
|
| 40 |
+
var_name = self.state[_Break].control_var_name
|
| 41 |
+
# TODO(mdan): This will fail when expanded inside a top-level else block.
|
| 42 |
+
template = """
|
| 43 |
+
var_name = True
|
| 44 |
+
continue
|
| 45 |
+
"""
|
| 46 |
+
return templates.replace(template, var_name=var_name)
|
| 47 |
+
|
| 48 |
+
def _guard_if_present(self, block, var_name):
|
| 49 |
+
"""Prevents the block from executing if var_name is set."""
|
| 50 |
+
if not block:
|
| 51 |
+
return block
|
| 52 |
+
|
| 53 |
+
template = """
|
| 54 |
+
if not var_name:
|
| 55 |
+
block
|
| 56 |
+
"""
|
| 57 |
+
node = templates.replace(
|
| 58 |
+
template,
|
| 59 |
+
var_name=var_name,
|
| 60 |
+
block=block)
|
| 61 |
+
return node
|
| 62 |
+
|
| 63 |
+
def _process_body(self, nodes, break_var):
|
| 64 |
+
self.state[_Break].enter()
|
| 65 |
+
self.state[_Break].control_var_name = break_var
|
| 66 |
+
nodes = self.visit_block(nodes)
|
| 67 |
+
break_used = self.state[_Break].used
|
| 68 |
+
self.state[_Break].exit()
|
| 69 |
+
return nodes, break_used
|
| 70 |
+
|
| 71 |
+
def visit_While(self, node):
|
| 72 |
+
original_node = node
|
| 73 |
+
scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
|
| 74 |
+
break_var = self.ctx.namer.new_symbol('break_', scope.referenced)
|
| 75 |
+
|
| 76 |
+
node.test = self.visit(node.test)
|
| 77 |
+
node.body, break_used = self._process_body(node.body, break_var)
|
| 78 |
+
# A break in the else clause applies to the containing scope.
|
| 79 |
+
node.orelse = self.visit_block(node.orelse)
|
| 80 |
+
|
| 81 |
+
if not break_used:
|
| 82 |
+
template = """
|
| 83 |
+
while test:
|
| 84 |
+
body
|
| 85 |
+
orelse
|
| 86 |
+
"""
|
| 87 |
+
node = templates.replace(
|
| 88 |
+
template, test=node.test, body=node.body, orelse=node.orelse)
|
| 89 |
+
|
| 90 |
+
new_while_node = node[0]
|
| 91 |
+
anno.copyanno(original_node, new_while_node, anno.Basic.DIRECTIVES)
|
| 92 |
+
|
| 93 |
+
return node
|
| 94 |
+
|
| 95 |
+
# Python's else clause only triggers if the loop exited cleanly (e.g.
|
| 96 |
+
# break did not trigger).
|
| 97 |
+
guarded_orelse = self._guard_if_present(node.orelse, break_var)
|
| 98 |
+
|
| 99 |
+
template = """
|
| 100 |
+
var_name = False
|
| 101 |
+
while not var_name and test:
|
| 102 |
+
body
|
| 103 |
+
orelse
|
| 104 |
+
"""
|
| 105 |
+
node = templates.replace(
|
| 106 |
+
template,
|
| 107 |
+
var_name=break_var,
|
| 108 |
+
test=node.test,
|
| 109 |
+
body=node.body,
|
| 110 |
+
orelse=guarded_orelse)
|
| 111 |
+
|
| 112 |
+
new_while_node = node[1]
|
| 113 |
+
anno.copyanno(original_node, new_while_node, anno.Basic.DIRECTIVES)
|
| 114 |
+
|
| 115 |
+
return node
|
| 116 |
+
|
| 117 |
+
def visit_For(self, node):
|
| 118 |
+
original_node = node
|
| 119 |
+
scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
|
| 120 |
+
break_var = self.ctx.namer.new_symbol('break_', scope.referenced)
|
| 121 |
+
|
| 122 |
+
node.target = self.visit(node.target)
|
| 123 |
+
node.iter = self.visit(node.iter)
|
| 124 |
+
node.body, break_used = self._process_body(node.body, break_var)
|
| 125 |
+
# A break in the else clause applies to the containing scope.
|
| 126 |
+
node.orelse = self.visit_block(node.orelse)
|
| 127 |
+
|
| 128 |
+
if not break_used:
|
| 129 |
+
template = """
|
| 130 |
+
for target in iter_:
|
| 131 |
+
body
|
| 132 |
+
orelse
|
| 133 |
+
"""
|
| 134 |
+
node = templates.replace(
|
| 135 |
+
template,
|
| 136 |
+
iter_=node.iter,
|
| 137 |
+
target=node.target,
|
| 138 |
+
body=node.body,
|
| 139 |
+
orelse=node.orelse)
|
| 140 |
+
|
| 141 |
+
new_for_node = node[0]
|
| 142 |
+
anno.copyanno(original_node, new_for_node, anno.Basic.EXTRA_LOOP_TEST)
|
| 143 |
+
anno.copyanno(original_node, new_for_node, anno.Basic.DIRECTIVES)
|
| 144 |
+
|
| 145 |
+
return node
|
| 146 |
+
|
| 147 |
+
# Python's else clause only triggers if the loop exited cleanly (e.g.
|
| 148 |
+
# break did not trigger).
|
| 149 |
+
guarded_orelse = self._guard_if_present(node.orelse, break_var)
|
| 150 |
+
extra_test = templates.replace_as_expression(
|
| 151 |
+
'not var_name', var_name=break_var)
|
| 152 |
+
|
| 153 |
+
# The extra test is hidden in the AST, which will confuse the static
|
| 154 |
+
# analysis. To mitigate that, we insert a no-op statement that ensures
|
| 155 |
+
# the control variable is marked as used.
|
| 156 |
+
# TODO(mdan): Use a marker instead, e.g. ag__.condition_loop_on(var_name)
|
| 157 |
+
template = """
|
| 158 |
+
var_name = False
|
| 159 |
+
for target in iter_:
|
| 160 |
+
(var_name,)
|
| 161 |
+
body
|
| 162 |
+
orelse
|
| 163 |
+
"""
|
| 164 |
+
node = templates.replace(
|
| 165 |
+
template,
|
| 166 |
+
var_name=break_var,
|
| 167 |
+
iter_=node.iter,
|
| 168 |
+
target=node.target,
|
| 169 |
+
body=node.body,
|
| 170 |
+
orelse=guarded_orelse)
|
| 171 |
+
|
| 172 |
+
new_for_node = node[1]
|
| 173 |
+
anno.setanno(new_for_node, anno.Basic.EXTRA_LOOP_TEST, extra_test)
|
| 174 |
+
anno.copyanno(original_node, new_for_node, anno.Basic.DIRECTIVES)
|
| 175 |
+
|
| 176 |
+
return node
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def transform(node, ctx):
|
| 180 |
+
node = qual_names.resolve(node)
|
| 181 |
+
node = activity.resolve(node, ctx, None)
|
| 182 |
+
|
| 183 |
+
transformer = BreakTransformer(ctx)
|
| 184 |
+
node = transformer.visit(node)
|
| 185 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/call_trees.py
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Handles function calls, by generating compiled function names and calls.
|
| 16 |
+
|
| 17 |
+
Note: this transformer does not rename the top level object being converted;
|
| 18 |
+
that is the caller's responsibility.
|
| 19 |
+
|
| 20 |
+
Requires function_scopes.
|
| 21 |
+
"""
|
| 22 |
+
|
| 23 |
+
import gast
|
| 24 |
+
|
| 25 |
+
from tensorflow.python.autograph.core import converter
|
| 26 |
+
from tensorflow.python.autograph.pyct import anno
|
| 27 |
+
from tensorflow.python.autograph.pyct import parser
|
| 28 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 29 |
+
from tensorflow.python.autograph.pyct import templates
|
| 30 |
+
from tensorflow.python.autograph.utils import ag_logging
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
# TODO(mdan): Rename to FunctionCallsTransformer.
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class _Function(object):
|
| 37 |
+
|
| 38 |
+
no_root = True
|
| 39 |
+
|
| 40 |
+
def __init__(self):
|
| 41 |
+
self.context_name = None
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
set_trace_warned = False
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class _ArgTemplateBuilder(object):
|
| 48 |
+
"""Constructs a tuple representing the positional arguments in a call.
|
| 49 |
+
|
| 50 |
+
Example (yes, it's legal Python 3):
|
| 51 |
+
|
| 52 |
+
f(*args1, b, *args2, c, d) -> args1 + (b,) + args2 + (c, d)
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
def __init__(self):
|
| 56 |
+
self._arg_accumulator = []
|
| 57 |
+
self._argspec = []
|
| 58 |
+
self._finalized = False
|
| 59 |
+
|
| 60 |
+
def _consume_args(self):
|
| 61 |
+
if self._arg_accumulator:
|
| 62 |
+
self._argspec.append(
|
| 63 |
+
gast.Tuple(elts=self._arg_accumulator, ctx=gast.Load()))
|
| 64 |
+
self._arg_accumulator = []
|
| 65 |
+
|
| 66 |
+
def add_arg(self, a):
|
| 67 |
+
self._arg_accumulator.append(a)
|
| 68 |
+
|
| 69 |
+
def add_stararg(self, a):
|
| 70 |
+
self._consume_args()
|
| 71 |
+
self._argspec.append(
|
| 72 |
+
gast.Call(
|
| 73 |
+
gast.Name(
|
| 74 |
+
'tuple', ctx=gast.Load(), annotation=None, type_comment=None),
|
| 75 |
+
args=[a],
|
| 76 |
+
keywords=()))
|
| 77 |
+
|
| 78 |
+
def finalize(self):
|
| 79 |
+
self._consume_args()
|
| 80 |
+
self._finalized = True
|
| 81 |
+
|
| 82 |
+
def to_ast(self):
|
| 83 |
+
assert self._finalized
|
| 84 |
+
if self._argspec:
|
| 85 |
+
result = self._argspec[0]
|
| 86 |
+
for i in range(1, len(self._argspec)):
|
| 87 |
+
result = gast.BinOp(result, gast.Add(), self._argspec[i])
|
| 88 |
+
return result
|
| 89 |
+
return gast.Tuple([], gast.Load())
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
class CallTreeTransformer(converter.Base):
|
| 93 |
+
"""Transforms the call tree by renaming transformed symbols."""
|
| 94 |
+
|
| 95 |
+
def visit_Lambda(self, node):
|
| 96 |
+
if not anno.hasanno(node, 'function_context_name'):
|
| 97 |
+
# Lambda functions created during the conversion process have no
|
| 98 |
+
# context manager.
|
| 99 |
+
return self.generic_visit(node)
|
| 100 |
+
with self.state[_Function] as fn_scope:
|
| 101 |
+
fn_scope.context_name = anno.getanno(node, 'function_context_name')
|
| 102 |
+
return self.generic_visit(node)
|
| 103 |
+
|
| 104 |
+
def visit_FunctionDef(self, node):
|
| 105 |
+
# Decorators and arg defaults are part of the outer scope.
|
| 106 |
+
node.decorator_list = self.visit_block(node.decorator_list)
|
| 107 |
+
node.args.defaults = self.visit_block(node.args.defaults)
|
| 108 |
+
for i, d in enumerate(node.args.kw_defaults):
|
| 109 |
+
if d is not None:
|
| 110 |
+
node.args.kw_defaults[i] = self.visit(d)
|
| 111 |
+
with self.state[_Function] as fn_scope:
|
| 112 |
+
# Note: if the conversion process ever creates helper functions, this
|
| 113 |
+
# assumption will no longer hold.
|
| 114 |
+
assert anno.hasanno(node, 'function_context_name'), (
|
| 115 |
+
'The function_scopes converter always creates a scope for functions.')
|
| 116 |
+
fn_scope.context_name = anno.getanno(node, 'function_context_name')
|
| 117 |
+
node.body = self.visit_block(node.body)
|
| 118 |
+
if node.returns:
|
| 119 |
+
node.returns = self.visit(node.returns)
|
| 120 |
+
return node
|
| 121 |
+
|
| 122 |
+
def visit_With(self, node):
|
| 123 |
+
# Context manager calls (in node.items) are not converted.
|
| 124 |
+
node.body = self.visit_block(node.body)
|
| 125 |
+
return node
|
| 126 |
+
|
| 127 |
+
def _args_to_tuple(self, node):
|
| 128 |
+
"""Ties together all positional and *arg arguments in a single tuple."""
|
| 129 |
+
# TODO(mdan): We could rewrite this to just a call to tuple(). Maybe better?
|
| 130 |
+
# For example for
|
| 131 |
+
# f(a, b, *args)
|
| 132 |
+
# instead of writing:
|
| 133 |
+
# (a, b) + args
|
| 134 |
+
# just write this?
|
| 135 |
+
# tuple(a, b, *args)
|
| 136 |
+
builder = _ArgTemplateBuilder()
|
| 137 |
+
for a in node.args:
|
| 138 |
+
if isinstance(a, gast.Starred):
|
| 139 |
+
builder.add_stararg(a.value)
|
| 140 |
+
else:
|
| 141 |
+
builder.add_arg(a)
|
| 142 |
+
builder.finalize()
|
| 143 |
+
return builder.to_ast()
|
| 144 |
+
|
| 145 |
+
def _kwargs_to_dict(self, node):
|
| 146 |
+
"""Ties together all keyword and **kwarg arguments in a single dict."""
|
| 147 |
+
if node.keywords:
|
| 148 |
+
return gast.Call(
|
| 149 |
+
gast.Name(
|
| 150 |
+
'dict', ctx=gast.Load(), annotation=None, type_comment=None),
|
| 151 |
+
args=(),
|
| 152 |
+
keywords=node.keywords)
|
| 153 |
+
else:
|
| 154 |
+
return parser.parse_expression('None')
|
| 155 |
+
|
| 156 |
+
def visit_Call(self, node):
|
| 157 |
+
full_name = str(anno.getanno(node.func, anno.Basic.QN, default=''))
|
| 158 |
+
function_context_name = self.state[_Function].context_name
|
| 159 |
+
node = self.generic_visit(node)
|
| 160 |
+
|
| 161 |
+
# TODO(mdan): Refactor converted_call as a 'Call' operator.
|
| 162 |
+
|
| 163 |
+
# Calls to the internal 'ag__' module are never converted (though their
|
| 164 |
+
# arguments might be).
|
| 165 |
+
if full_name.startswith('ag__.'):
|
| 166 |
+
return node
|
| 167 |
+
|
| 168 |
+
# Calls to the function context manager (inserted by function_scopes) are
|
| 169 |
+
# also safe.
|
| 170 |
+
if full_name.startswith(function_context_name + '.'):
|
| 171 |
+
return node
|
| 172 |
+
|
| 173 |
+
# Calls to pdb.set_trace or ipdb.set_trace are never converted. We don't use
|
| 174 |
+
# the normal mechanisms to bypass these literals because they are sensitive
|
| 175 |
+
# to the frame they are being called from.
|
| 176 |
+
# TODO(mdan): Generalize this to a "static allowlist" config.
|
| 177 |
+
if full_name in ('pdb.set_trace', 'ipdb.set_trace', 'breakpoint'):
|
| 178 |
+
global set_trace_warned
|
| 179 |
+
if not set_trace_warned:
|
| 180 |
+
# TODO(mdan): Update and shorten once available on tensorflow.org.
|
| 181 |
+
ag_logging.warning(
|
| 182 |
+
'Detected `pdb.set_trace()` in user code. The code'
|
| 183 |
+
' generated by AutoGraph is not optimized for step-by-step'
|
| 184 |
+
' debugging. See https://github.com/tensorflow/tensorflow/'
|
| 185 |
+
'blob/master/tensorflow/python/autograph/g3doc/reference/'
|
| 186 |
+
'debugging.md.')
|
| 187 |
+
set_trace_warned = True
|
| 188 |
+
return node
|
| 189 |
+
|
| 190 |
+
if (full_name == 'print' and
|
| 191 |
+
not self.ctx.user.options.uses(converter.Feature.BUILTIN_FUNCTIONS)):
|
| 192 |
+
return node
|
| 193 |
+
|
| 194 |
+
template = """
|
| 195 |
+
ag__.converted_call(func, args, kwargs, function_ctx)
|
| 196 |
+
"""
|
| 197 |
+
new_call = templates.replace_as_expression(
|
| 198 |
+
template,
|
| 199 |
+
func=node.func,
|
| 200 |
+
args=self._args_to_tuple(node),
|
| 201 |
+
kwargs=self._kwargs_to_dict(node),
|
| 202 |
+
function_ctx=function_context_name)
|
| 203 |
+
|
| 204 |
+
return new_call
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
def transform(node, ctx):
|
| 208 |
+
"""Transform function call to the compiled counterparts.
|
| 209 |
+
|
| 210 |
+
Args:
|
| 211 |
+
node: AST
|
| 212 |
+
ctx: EntityContext
|
| 213 |
+
Returns:
|
| 214 |
+
A tuple (node, new_names):
|
| 215 |
+
node: The transformed AST
|
| 216 |
+
new_names: set(string), containing any newly-generated names
|
| 217 |
+
"""
|
| 218 |
+
node = qual_names.resolve(node)
|
| 219 |
+
|
| 220 |
+
node = CallTreeTransformer(ctx).visit(node)
|
| 221 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/conditional_expressions.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converts the ternary conditional operator."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import parser
|
| 21 |
+
from tensorflow.python.autograph.pyct import templates
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class ConditionalExpressionTransformer(converter.Base):
|
| 25 |
+
"""Converts conditional expressions to functional form."""
|
| 26 |
+
|
| 27 |
+
def visit_IfExp(self, node):
|
| 28 |
+
template = '''
|
| 29 |
+
ag__.if_exp(
|
| 30 |
+
test,
|
| 31 |
+
lambda: true_expr,
|
| 32 |
+
lambda: false_expr,
|
| 33 |
+
expr_repr)
|
| 34 |
+
'''
|
| 35 |
+
expr_repr = parser.unparse(node.test, include_encoding_marker=False).strip()
|
| 36 |
+
return templates.replace_as_expression(
|
| 37 |
+
template,
|
| 38 |
+
test=node.test,
|
| 39 |
+
true_expr=node.body,
|
| 40 |
+
false_expr=node.orelse,
|
| 41 |
+
expr_repr=gast.Constant(expr_repr, kind=None))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def transform(node, ctx):
|
| 45 |
+
node = ConditionalExpressionTransformer(ctx).visit(node)
|
| 46 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/continue_statements.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Canonicalizes continue statements by de-sugaring into a control boolean."""
|
| 16 |
+
|
| 17 |
+
from tensorflow.python.autograph.core import converter
|
| 18 |
+
from tensorflow.python.autograph.pyct import anno
|
| 19 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 20 |
+
from tensorflow.python.autograph.pyct import templates
|
| 21 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 22 |
+
from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class _Continue(object):
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self.used = False
|
| 29 |
+
self.control_var_name = None
|
| 30 |
+
|
| 31 |
+
def __repr__(self):
|
| 32 |
+
return '<_Continue(used: {}, var: {})>'.format(self.used,
|
| 33 |
+
self.control_var_name)
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class _Block(object):
|
| 37 |
+
"""Tracks information about lexical blocks as they are visited in the AST.
|
| 38 |
+
|
| 39 |
+
Mainly, this object tracks the creation of block guards that replace
|
| 40 |
+
`continue` statements (e.g. `if not continue_:`).
|
| 41 |
+
|
| 42 |
+
Attributes:
|
| 43 |
+
create_guard_current: bool, whether to create a guard for the current
|
| 44 |
+
statement.
|
| 45 |
+
create_guard_next: bool, whether to create a guard for the next
|
| 46 |
+
statement.
|
| 47 |
+
is_loop_type: bool, whether this block is the body of a loop.
|
| 48 |
+
"""
|
| 49 |
+
|
| 50 |
+
def __init__(self):
|
| 51 |
+
self.is_loop_type = False
|
| 52 |
+
self.create_guard_current = False
|
| 53 |
+
self.create_guard_next = False
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class ContinueCanonicalizationTransformer(converter.Base):
|
| 57 |
+
"""Canonicalizes continue statements into additional conditionals."""
|
| 58 |
+
|
| 59 |
+
def visit_Continue(self, node):
|
| 60 |
+
self.state[_Continue].used = True
|
| 61 |
+
for block in reversed(self.state[_Block].stack):
|
| 62 |
+
# See ContinueCanonicalizationTest.test_multiple_continues for an example
|
| 63 |
+
# it's necessary to create guards for all enclosing affected blocks, not
|
| 64 |
+
# just that of the current block.
|
| 65 |
+
block.create_guard_next = True
|
| 66 |
+
if block.is_loop_type:
|
| 67 |
+
# continue only affects the innermost loop
|
| 68 |
+
break
|
| 69 |
+
template = """
|
| 70 |
+
var_name = True
|
| 71 |
+
"""
|
| 72 |
+
return templates.replace(
|
| 73 |
+
template, var_name=self.state[_Continue].control_var_name)
|
| 74 |
+
|
| 75 |
+
def _postprocess_statement(self, node):
|
| 76 |
+
if self.state[_Continue].used:
|
| 77 |
+
block = self.state[_Block]
|
| 78 |
+
should_wrap_current = block.create_guard_current
|
| 79 |
+
# After processing propagate whether to guard the next statement
|
| 80 |
+
block.create_guard_current = block.create_guard_next
|
| 81 |
+
block.create_guard_next = False
|
| 82 |
+
if should_wrap_current:
|
| 83 |
+
template = """
|
| 84 |
+
if not var_name:
|
| 85 |
+
original_node
|
| 86 |
+
"""
|
| 87 |
+
cond, = templates.replace(
|
| 88 |
+
template,
|
| 89 |
+
var_name=self.state[_Continue].control_var_name,
|
| 90 |
+
original_node=node)
|
| 91 |
+
return cond, cond.body
|
| 92 |
+
return node, None
|
| 93 |
+
|
| 94 |
+
def _visit_loop_body(self, node, nodes):
|
| 95 |
+
self.state[_Continue].enter()
|
| 96 |
+
self.state[_Block].enter()
|
| 97 |
+
self.state[_Block].is_loop_type = True
|
| 98 |
+
scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
|
| 99 |
+
continue_var = self.ctx.namer.new_symbol('continue_', scope.referenced)
|
| 100 |
+
self.state[_Continue].control_var_name = continue_var
|
| 101 |
+
|
| 102 |
+
nodes = self.visit_block(nodes, after_visit=self._postprocess_statement)
|
| 103 |
+
|
| 104 |
+
if self.state[_Continue].used:
|
| 105 |
+
template = """
|
| 106 |
+
var_name = False
|
| 107 |
+
"""
|
| 108 |
+
control_var_init = templates.replace(template, var_name=continue_var)
|
| 109 |
+
nodes = control_var_init + nodes
|
| 110 |
+
|
| 111 |
+
self.state[_Block].exit()
|
| 112 |
+
self.state[_Continue].exit()
|
| 113 |
+
return nodes
|
| 114 |
+
|
| 115 |
+
def _visit_non_loop_body(self, nodes):
|
| 116 |
+
self.state[_Block].enter()
|
| 117 |
+
nodes = self.visit_block(nodes, after_visit=self._postprocess_statement)
|
| 118 |
+
self.state[_Block].exit()
|
| 119 |
+
return nodes
|
| 120 |
+
|
| 121 |
+
def visit_While(self, node):
|
| 122 |
+
node.test = self.visit(node.test)
|
| 123 |
+
node.body = self._visit_loop_body(node, node.body)
|
| 124 |
+
# A continue in the else clause applies to the containing scope.
|
| 125 |
+
node.orelse = self._visit_non_loop_body(node.orelse)
|
| 126 |
+
return node
|
| 127 |
+
|
| 128 |
+
def visit_For(self, node):
|
| 129 |
+
node.target = self.generic_visit(node.target)
|
| 130 |
+
node.iter = self.generic_visit(node.iter)
|
| 131 |
+
node.body = self._visit_loop_body(node, node.body)
|
| 132 |
+
# A continue in the else clause applies to the containing scope.
|
| 133 |
+
node.orelse = self._visit_non_loop_body(node.orelse)
|
| 134 |
+
return node
|
| 135 |
+
|
| 136 |
+
def visit_If(self, node):
|
| 137 |
+
node.body = self._visit_non_loop_body(node.body)
|
| 138 |
+
node.orelse = self._visit_non_loop_body(node.orelse)
|
| 139 |
+
return node
|
| 140 |
+
|
| 141 |
+
def visit_With(self, node):
|
| 142 |
+
node.items = self.visit_block(node.items)
|
| 143 |
+
node.body = self._visit_non_loop_body(node.body)
|
| 144 |
+
return node
|
| 145 |
+
|
| 146 |
+
def visit_Try(self, node):
|
| 147 |
+
node.body = self._visit_non_loop_body(node.body)
|
| 148 |
+
node.orelse = self._visit_non_loop_body(node.orelse)
|
| 149 |
+
# In Python 3.8 and later continue is allowed in finally blocks
|
| 150 |
+
node.finalbody = self._visit_non_loop_body(node.finalbody)
|
| 151 |
+
node.handlers = self.visit_block(node.handlers)
|
| 152 |
+
return node
|
| 153 |
+
|
| 154 |
+
def visit_ExceptHandler(self, node):
|
| 155 |
+
node.body = self._visit_non_loop_body(node.body)
|
| 156 |
+
return node
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def transform(node, ctx):
|
| 160 |
+
node = qual_names.resolve(node)
|
| 161 |
+
node = activity.resolve(node, ctx, None)
|
| 162 |
+
|
| 163 |
+
node = ContinueCanonicalizationTransformer(ctx).visit(node)
|
| 164 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/control_flow.py
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Handles control flow statements: while, for, if."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.lang import directives
|
| 21 |
+
from tensorflow.python.autograph.pyct import anno
|
| 22 |
+
from tensorflow.python.autograph.pyct import cfg
|
| 23 |
+
from tensorflow.python.autograph.pyct import origin_info
|
| 24 |
+
from tensorflow.python.autograph.pyct import parser
|
| 25 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 26 |
+
from tensorflow.python.autograph.pyct import templates
|
| 27 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 28 |
+
from tensorflow.python.autograph.pyct.static_analysis import annos
|
| 29 |
+
from tensorflow.python.autograph.pyct.static_analysis import liveness
|
| 30 |
+
from tensorflow.python.autograph.pyct.static_analysis import reaching_definitions
|
| 31 |
+
from tensorflow.python.autograph.pyct.static_analysis import reaching_fndefs
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class _Function(object):
|
| 35 |
+
|
| 36 |
+
scope = None
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
class ControlFlowTransformer(converter.Base):
|
| 40 |
+
"""Transforms control flow structures like loops an conditionals."""
|
| 41 |
+
|
| 42 |
+
def visit_Lambda(self, node):
|
| 43 |
+
with self.state[_Function] as fn:
|
| 44 |
+
fn.scope = anno.getanno(node, anno.Static.SCOPE)
|
| 45 |
+
return self.generic_visit(node)
|
| 46 |
+
|
| 47 |
+
def visit_FunctionDef(self, node):
|
| 48 |
+
with self.state[_Function] as fn:
|
| 49 |
+
fn.scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE)
|
| 50 |
+
return self.generic_visit(node)
|
| 51 |
+
|
| 52 |
+
def _create_nonlocal_declarations(self, vars_):
|
| 53 |
+
vars_ = set(vars_)
|
| 54 |
+
results = []
|
| 55 |
+
global_vars = self.state[_Function].scope.globals & vars_
|
| 56 |
+
|
| 57 |
+
if global_vars:
|
| 58 |
+
results.append(gast.Global([str(v) for v in global_vars]))
|
| 59 |
+
|
| 60 |
+
nonlocal_vars = [
|
| 61 |
+
v for v in vars_ if not v.is_composite() and v not in global_vars]
|
| 62 |
+
if nonlocal_vars:
|
| 63 |
+
results.append(gast.Nonlocal([str(v) for v in nonlocal_vars]))
|
| 64 |
+
|
| 65 |
+
return results
|
| 66 |
+
|
| 67 |
+
def _create_state_functions(
|
| 68 |
+
self, block_vars, nonlocal_declarations, getter_name, setter_name):
|
| 69 |
+
if not block_vars:
|
| 70 |
+
template = """
|
| 71 |
+
def getter_name():
|
| 72 |
+
return ()
|
| 73 |
+
def setter_name(block_vars):
|
| 74 |
+
pass
|
| 75 |
+
"""
|
| 76 |
+
return templates.replace(
|
| 77 |
+
template, getter_name=getter_name, setter_name=setter_name)
|
| 78 |
+
|
| 79 |
+
guarded_block_vars = []
|
| 80 |
+
for v in block_vars:
|
| 81 |
+
if v.is_simple():
|
| 82 |
+
guarded_block_vars.append(v)
|
| 83 |
+
else:
|
| 84 |
+
guarded_block_vars.append(
|
| 85 |
+
templates.replace_as_expression(
|
| 86 |
+
'ag__.ldu(lambda: var_, name)',
|
| 87 |
+
var_=v,
|
| 88 |
+
name=gast.Constant(str(v), kind=None)))
|
| 89 |
+
|
| 90 |
+
template = """
|
| 91 |
+
def getter_name():
|
| 92 |
+
return guarded_state_vars,
|
| 93 |
+
def setter_name(vars_):
|
| 94 |
+
nonlocal_declarations
|
| 95 |
+
state_vars, = vars_
|
| 96 |
+
"""
|
| 97 |
+
return templates.replace(
|
| 98 |
+
template,
|
| 99 |
+
nonlocal_declarations=nonlocal_declarations,
|
| 100 |
+
getter_name=getter_name,
|
| 101 |
+
guarded_state_vars=guarded_block_vars,
|
| 102 |
+
setter_name=setter_name,
|
| 103 |
+
state_vars=tuple(block_vars))
|
| 104 |
+
|
| 105 |
+
def _create_loop_options(self, node):
|
| 106 |
+
if not anno.hasanno(node, anno.Basic.DIRECTIVES):
|
| 107 |
+
return gast.Dict([], [])
|
| 108 |
+
|
| 109 |
+
loop_directives = anno.getanno(node, anno.Basic.DIRECTIVES)
|
| 110 |
+
if directives.set_loop_options not in loop_directives:
|
| 111 |
+
return gast.Dict([], [])
|
| 112 |
+
|
| 113 |
+
opts_dict = loop_directives[directives.set_loop_options]
|
| 114 |
+
str_keys, values = zip(*opts_dict.items())
|
| 115 |
+
keys = [gast.Constant(s, kind=None) for s in str_keys]
|
| 116 |
+
values = list(values) # ast and gast don't play well with tuples.
|
| 117 |
+
return gast.Dict(keys, values)
|
| 118 |
+
|
| 119 |
+
def _create_undefined_assigns(self, undefined_symbols):
|
| 120 |
+
assignments = []
|
| 121 |
+
for s in undefined_symbols:
|
| 122 |
+
template = '''
|
| 123 |
+
var = ag__.Undefined(symbol_name)
|
| 124 |
+
'''
|
| 125 |
+
assignments += templates.replace(
|
| 126 |
+
template,
|
| 127 |
+
var=s,
|
| 128 |
+
symbol_name=gast.Constant(s.ssf(), kind=None))
|
| 129 |
+
return assignments
|
| 130 |
+
|
| 131 |
+
def _get_block_basic_vars(self, modified, live_in, live_out):
|
| 132 |
+
nonlocals = self.state[_Function].scope.nonlocals
|
| 133 |
+
basic_scope_vars = []
|
| 134 |
+
for s in modified:
|
| 135 |
+
if s.is_composite():
|
| 136 |
+
# TODO(mdan): Raise an error when this happens for a TF scope.
|
| 137 |
+
continue
|
| 138 |
+
# Variables not live into or out of the scope are considered local to the
|
| 139 |
+
# scope.
|
| 140 |
+
if s in live_in or s in live_out or s in nonlocals:
|
| 141 |
+
basic_scope_vars.append(s)
|
| 142 |
+
continue
|
| 143 |
+
return frozenset(basic_scope_vars)
|
| 144 |
+
|
| 145 |
+
def _get_block_composite_vars(self, modified, live_in):
|
| 146 |
+
# The scope variables corresponding to composite symbols (e.g. `self.x`).
|
| 147 |
+
composite_scope_vars = []
|
| 148 |
+
for s in modified:
|
| 149 |
+
if not s.is_composite():
|
| 150 |
+
continue
|
| 151 |
+
# Mutations made to objects created inside the scope will appear as writes
|
| 152 |
+
# to composite symbols. Because these mutations appear as modifications
|
| 153 |
+
# made to composite symbols, we check whether the composite's parent is
|
| 154 |
+
# actually live into the scope.
|
| 155 |
+
# Example:
|
| 156 |
+
# while cond:
|
| 157 |
+
# x = Foo()
|
| 158 |
+
# x.foo = 2 * x.foo # x.foo is live into the scope, but x is not.
|
| 159 |
+
#
|
| 160 |
+
# Note that some parents might not be symbols - for example, in x['foo'],
|
| 161 |
+
# 'foo' is a parent, but it's a literal, not a symbol. We don't check the
|
| 162 |
+
# liveness of literals.
|
| 163 |
+
support_set_symbols = tuple(
|
| 164 |
+
sss for sss in s.support_set if sss.is_symbol())
|
| 165 |
+
if not all(sss in live_in for sss in support_set_symbols):
|
| 166 |
+
continue
|
| 167 |
+
composite_scope_vars.append(s)
|
| 168 |
+
return frozenset(composite_scope_vars)
|
| 169 |
+
|
| 170 |
+
def _get_block_vars(self, node, modified):
|
| 171 |
+
"""Determines the variables affected inside a control flow statement."""
|
| 172 |
+
defined_in = anno.getanno(node, anno.Static.DEFINED_VARS_IN)
|
| 173 |
+
live_in = anno.getanno(node, anno.Static.LIVE_VARS_IN)
|
| 174 |
+
live_out = anno.getanno(node, anno.Static.LIVE_VARS_OUT)
|
| 175 |
+
fn_scope = self.state[_Function].scope
|
| 176 |
+
|
| 177 |
+
basic_scope_vars = self._get_block_basic_vars(
|
| 178 |
+
modified,
|
| 179 |
+
live_in,
|
| 180 |
+
live_out)
|
| 181 |
+
composite_scope_vars = self._get_block_composite_vars(modified, live_in)
|
| 182 |
+
scope_vars = tuple(basic_scope_vars | composite_scope_vars)
|
| 183 |
+
|
| 184 |
+
# Variables that are modified inside the scope, but not defined
|
| 185 |
+
# before entering it. Only simple variables must be defined. The
|
| 186 |
+
# composite ones will be implicitly checked at runtime.
|
| 187 |
+
possibly_undefined = (
|
| 188 |
+
modified - defined_in - fn_scope.globals - fn_scope.nonlocals)
|
| 189 |
+
undefined = tuple(v for v in possibly_undefined if not v.is_composite())
|
| 190 |
+
|
| 191 |
+
# Variables that are modified inside the scope, and depend on values outside
|
| 192 |
+
# it.
|
| 193 |
+
input_only = basic_scope_vars & live_in - live_out
|
| 194 |
+
|
| 195 |
+
# Place the outputs first, then sort lexicographically.
|
| 196 |
+
scope_vars = sorted(scope_vars, key=lambda v: (v in input_only, v))
|
| 197 |
+
nouts = len(scope_vars) - len(input_only)
|
| 198 |
+
|
| 199 |
+
return scope_vars, undefined, nouts
|
| 200 |
+
|
| 201 |
+
def visit_If(self, node):
|
| 202 |
+
node = self.generic_visit(node)
|
| 203 |
+
body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE)
|
| 204 |
+
orelse_scope = anno.getanno(node, annos.NodeAnno.ORELSE_SCOPE)
|
| 205 |
+
|
| 206 |
+
cond_vars, undefined, nouts = self._get_block_vars(
|
| 207 |
+
node, body_scope.bound | orelse_scope.bound)
|
| 208 |
+
|
| 209 |
+
undefined_assigns = self._create_undefined_assigns(undefined)
|
| 210 |
+
|
| 211 |
+
nonlocal_declarations = self._create_nonlocal_declarations(cond_vars)
|
| 212 |
+
|
| 213 |
+
reserved = body_scope.referenced | orelse_scope.referenced
|
| 214 |
+
state_getter_name = self.ctx.namer.new_symbol('get_state', reserved)
|
| 215 |
+
state_setter_name = self.ctx.namer.new_symbol('set_state', reserved)
|
| 216 |
+
state_functions = self._create_state_functions(
|
| 217 |
+
cond_vars, nonlocal_declarations, state_getter_name, state_setter_name)
|
| 218 |
+
|
| 219 |
+
orelse_body = node.orelse
|
| 220 |
+
if not orelse_body:
|
| 221 |
+
orelse_body = [gast.Pass()]
|
| 222 |
+
|
| 223 |
+
template = """
|
| 224 |
+
state_functions
|
| 225 |
+
def body_name():
|
| 226 |
+
nonlocal_declarations
|
| 227 |
+
body
|
| 228 |
+
def orelse_name():
|
| 229 |
+
nonlocal_declarations
|
| 230 |
+
orelse
|
| 231 |
+
undefined_assigns
|
| 232 |
+
ag__.if_stmt(
|
| 233 |
+
test,
|
| 234 |
+
body_name,
|
| 235 |
+
orelse_name,
|
| 236 |
+
state_getter_name,
|
| 237 |
+
state_setter_name,
|
| 238 |
+
(symbol_names,),
|
| 239 |
+
nouts)
|
| 240 |
+
"""
|
| 241 |
+
new_nodes = templates.replace(
|
| 242 |
+
template,
|
| 243 |
+
body=node.body,
|
| 244 |
+
body_name=self.ctx.namer.new_symbol('if_body', reserved),
|
| 245 |
+
orelse=orelse_body,
|
| 246 |
+
orelse_name=self.ctx.namer.new_symbol('else_body', reserved),
|
| 247 |
+
nonlocal_declarations=nonlocal_declarations,
|
| 248 |
+
nouts=gast.Constant(nouts, kind=None),
|
| 249 |
+
state_functions=state_functions,
|
| 250 |
+
state_getter_name=state_getter_name,
|
| 251 |
+
state_setter_name=state_setter_name,
|
| 252 |
+
symbol_names=tuple(gast.Constant(str(s), kind=None) for s in cond_vars),
|
| 253 |
+
test=node.test,
|
| 254 |
+
undefined_assigns=undefined_assigns)
|
| 255 |
+
origin_info.copy_origin(node, new_nodes[-1])
|
| 256 |
+
return new_nodes
|
| 257 |
+
|
| 258 |
+
def visit_While(self, node):
|
| 259 |
+
node = self.generic_visit(node)
|
| 260 |
+
body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE)
|
| 261 |
+
|
| 262 |
+
loop_vars, undefined, _ = self._get_block_vars(node, body_scope.bound)
|
| 263 |
+
|
| 264 |
+
undefined_assigns = self._create_undefined_assigns(undefined)
|
| 265 |
+
|
| 266 |
+
nonlocal_declarations = self._create_nonlocal_declarations(loop_vars)
|
| 267 |
+
|
| 268 |
+
reserved = body_scope.referenced
|
| 269 |
+
state_getter_name = self.ctx.namer.new_symbol('get_state', reserved)
|
| 270 |
+
state_setter_name = self.ctx.namer.new_symbol('set_state', reserved)
|
| 271 |
+
state_functions = self._create_state_functions(
|
| 272 |
+
loop_vars, nonlocal_declarations, state_getter_name, state_setter_name)
|
| 273 |
+
|
| 274 |
+
opts = self._create_loop_options(node)
|
| 275 |
+
|
| 276 |
+
template = """
|
| 277 |
+
state_functions
|
| 278 |
+
def body_name():
|
| 279 |
+
nonlocal_declarations
|
| 280 |
+
body
|
| 281 |
+
def test_name():
|
| 282 |
+
return test
|
| 283 |
+
undefined_assigns
|
| 284 |
+
ag__.while_stmt(
|
| 285 |
+
test_name,
|
| 286 |
+
body_name,
|
| 287 |
+
state_getter_name,
|
| 288 |
+
state_setter_name,
|
| 289 |
+
(symbol_names,),
|
| 290 |
+
opts)
|
| 291 |
+
"""
|
| 292 |
+
new_nodes = templates.replace(
|
| 293 |
+
template,
|
| 294 |
+
body=node.body,
|
| 295 |
+
body_name=self.ctx.namer.new_symbol('loop_body', reserved),
|
| 296 |
+
nonlocal_declarations=nonlocal_declarations,
|
| 297 |
+
opts=opts,
|
| 298 |
+
state_functions=state_functions,
|
| 299 |
+
state_getter_name=state_getter_name,
|
| 300 |
+
state_setter_name=state_setter_name,
|
| 301 |
+
symbol_names=tuple(gast.Constant(str(s), kind=None) for s in loop_vars),
|
| 302 |
+
test=node.test,
|
| 303 |
+
test_name=self.ctx.namer.new_symbol('loop_test', reserved),
|
| 304 |
+
undefined_assigns=undefined_assigns)
|
| 305 |
+
origin_info.copy_origin(node, new_nodes[-1])
|
| 306 |
+
return new_nodes
|
| 307 |
+
|
| 308 |
+
def visit_For(self, node):
|
| 309 |
+
node = self.generic_visit(node)
|
| 310 |
+
body_scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE)
|
| 311 |
+
iter_scope = anno.getanno(node, annos.NodeAnno.ITERATE_SCOPE)
|
| 312 |
+
|
| 313 |
+
loop_vars, undefined, _ = self._get_block_vars(
|
| 314 |
+
node, body_scope.bound | iter_scope.bound)
|
| 315 |
+
|
| 316 |
+
undefined_assigns = self._create_undefined_assigns(undefined)
|
| 317 |
+
|
| 318 |
+
nonlocal_declarations = self._create_nonlocal_declarations(loop_vars)
|
| 319 |
+
|
| 320 |
+
reserved = body_scope.referenced | iter_scope.referenced
|
| 321 |
+
state_getter_name = self.ctx.namer.new_symbol('get_state', reserved)
|
| 322 |
+
state_setter_name = self.ctx.namer.new_symbol('set_state', reserved)
|
| 323 |
+
state_functions = self._create_state_functions(
|
| 324 |
+
loop_vars, nonlocal_declarations, state_getter_name, state_setter_name)
|
| 325 |
+
|
| 326 |
+
opts = self._create_loop_options(node)
|
| 327 |
+
opts.keys.append(gast.Constant('iterate_names', kind=None))
|
| 328 |
+
opts.values.append(gast.Constant(
|
| 329 |
+
parser.unparse(node.target, include_encoding_marker=False), kind=None))
|
| 330 |
+
|
| 331 |
+
if anno.hasanno(node, anno.Basic.EXTRA_LOOP_TEST):
|
| 332 |
+
extra_test = anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST)
|
| 333 |
+
extra_test_name = self.ctx.namer.new_symbol(
|
| 334 |
+
'extra_test', reserved)
|
| 335 |
+
template = """
|
| 336 |
+
def extra_test_name():
|
| 337 |
+
nonlocal_declarations
|
| 338 |
+
return extra_test_expr
|
| 339 |
+
"""
|
| 340 |
+
extra_test_function = templates.replace(
|
| 341 |
+
template,
|
| 342 |
+
extra_test_expr=extra_test,
|
| 343 |
+
extra_test_name=extra_test_name,
|
| 344 |
+
loop_vars=loop_vars,
|
| 345 |
+
nonlocal_declarations=nonlocal_declarations)
|
| 346 |
+
else:
|
| 347 |
+
extra_test_name = parser.parse_expression('None')
|
| 348 |
+
extra_test_function = []
|
| 349 |
+
|
| 350 |
+
# iterate_arg_name holds a single arg with the iterates, which may be a
|
| 351 |
+
# tuple.
|
| 352 |
+
iterate_arg_name = self.ctx.namer.new_symbol('itr', reserved)
|
| 353 |
+
template = """
|
| 354 |
+
iterates = iterate_arg_name
|
| 355 |
+
"""
|
| 356 |
+
iterate_expansion = templates.replace(
|
| 357 |
+
template, iterate_arg_name=iterate_arg_name, iterates=node.target)
|
| 358 |
+
origin_info.copy_origin(node, iterate_expansion)
|
| 359 |
+
|
| 360 |
+
template = """
|
| 361 |
+
state_functions
|
| 362 |
+
def body_name(iterate_arg_name):
|
| 363 |
+
nonlocal_declarations
|
| 364 |
+
iterate_expansion
|
| 365 |
+
body
|
| 366 |
+
extra_test_function
|
| 367 |
+
undefined_assigns
|
| 368 |
+
ag__.for_stmt(
|
| 369 |
+
iterated,
|
| 370 |
+
extra_test_name,
|
| 371 |
+
body_name,
|
| 372 |
+
state_getter_name,
|
| 373 |
+
state_setter_name,
|
| 374 |
+
(symbol_names,),
|
| 375 |
+
opts)
|
| 376 |
+
"""
|
| 377 |
+
new_nodes = templates.replace(
|
| 378 |
+
template,
|
| 379 |
+
body=node.body,
|
| 380 |
+
body_name=self.ctx.namer.new_symbol('loop_body', reserved),
|
| 381 |
+
extra_test_function=extra_test_function,
|
| 382 |
+
extra_test_name=extra_test_name,
|
| 383 |
+
iterate_arg_name=iterate_arg_name,
|
| 384 |
+
iterate_expansion=iterate_expansion,
|
| 385 |
+
iterated=node.iter,
|
| 386 |
+
nonlocal_declarations=nonlocal_declarations,
|
| 387 |
+
opts=opts,
|
| 388 |
+
symbol_names=tuple(gast.Constant(str(s), kind=None) for s in loop_vars),
|
| 389 |
+
state_functions=state_functions,
|
| 390 |
+
state_getter_name=state_getter_name,
|
| 391 |
+
state_setter_name=state_setter_name,
|
| 392 |
+
undefined_assigns=undefined_assigns)
|
| 393 |
+
origin_info.copy_origin(node, new_nodes[-1])
|
| 394 |
+
return new_nodes
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
class AnnotatedDef(reaching_definitions.Definition):
|
| 398 |
+
|
| 399 |
+
def __init__(self):
|
| 400 |
+
super(AnnotatedDef, self).__init__()
|
| 401 |
+
self.directives = {}
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
def transform(node, ctx):
|
| 405 |
+
graphs = cfg.build(node)
|
| 406 |
+
node = qual_names.resolve(node)
|
| 407 |
+
node = activity.resolve(node, ctx, None)
|
| 408 |
+
node = reaching_definitions.resolve(node, ctx, graphs)
|
| 409 |
+
node = reaching_fndefs.resolve(node, ctx, graphs)
|
| 410 |
+
node = liveness.resolve(node, ctx, graphs)
|
| 411 |
+
|
| 412 |
+
node = ControlFlowTransformer(ctx).visit(node)
|
| 413 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/directives.py
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Handles directives.
|
| 16 |
+
|
| 17 |
+
This converter removes the directive functions from the code and moves the
|
| 18 |
+
information they specify into AST annotations. It is a specialized form of
|
| 19 |
+
static analysis, one that is specific to AutoGraph.
|
| 20 |
+
|
| 21 |
+
Note that this requires that the actual directive functions are static - that
|
| 22 |
+
is, they do not change at runtime. So if you do something like this:
|
| 23 |
+
|
| 24 |
+
tf.autograph.set_loop_options = <new function>
|
| 25 |
+
|
| 26 |
+
Then the directive will may no longer be recognized. Furthermore, if the
|
| 27 |
+
converted function is cached, such an action may be irreversible.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
import inspect
|
| 31 |
+
|
| 32 |
+
import gast
|
| 33 |
+
|
| 34 |
+
from tensorflow.python.autograph.core import converter
|
| 35 |
+
from tensorflow.python.autograph.lang import directives
|
| 36 |
+
from tensorflow.python.autograph.pyct import anno
|
| 37 |
+
from tensorflow.python.util import tf_inspect
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
STATIC_VALUE = 'static_value'
|
| 41 |
+
"""Used for AST annotations, see visit_Name."""
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class _LoopScope(object):
|
| 45 |
+
|
| 46 |
+
def __init__(self):
|
| 47 |
+
self.ast_node = None
|
| 48 |
+
self.statements_visited = 0
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def _map_args(call_node, function):
|
| 52 |
+
"""Maps AST call nodes to the actual function's arguments.
|
| 53 |
+
|
| 54 |
+
Args:
|
| 55 |
+
call_node: ast.Call
|
| 56 |
+
function: Callable[..., Any], the actual function matching call_node
|
| 57 |
+
Returns:
|
| 58 |
+
Dict[Text, ast.AST], mapping each of the function's argument names to
|
| 59 |
+
the respective AST node.
|
| 60 |
+
Raises:
|
| 61 |
+
ValueError: if the default arguments are not correctly set
|
| 62 |
+
"""
|
| 63 |
+
args = call_node.args
|
| 64 |
+
kwds = {kwd.arg: kwd.value for kwd in call_node.keywords}
|
| 65 |
+
call_args = tf_inspect.getcallargs(function, *args, **kwds)
|
| 66 |
+
|
| 67 |
+
# Keyword arguments not specified in kwds will be mapped to their defaults,
|
| 68 |
+
# which are Python values. Since we don't currently have a way to transform
|
| 69 |
+
# those into AST references, we simply remove them. By convention, directives
|
| 70 |
+
# use UNSPECIFIED as default value for optional arguments. No other
|
| 71 |
+
# defaults should be present.
|
| 72 |
+
unexpected_defaults = []
|
| 73 |
+
for k in call_args:
|
| 74 |
+
if (k not in kwds
|
| 75 |
+
and call_args[k] not in args
|
| 76 |
+
and call_args[k] is not directives.UNSPECIFIED):
|
| 77 |
+
unexpected_defaults.append(k)
|
| 78 |
+
if unexpected_defaults:
|
| 79 |
+
raise ValueError('Unexpected keyword argument values, %s, for function %s'
|
| 80 |
+
% (zip(unexpected_defaults,
|
| 81 |
+
[call_args[k] for k in unexpected_defaults]),
|
| 82 |
+
function))
|
| 83 |
+
return {k: v for k, v in call_args.items() if v is not directives.UNSPECIFIED}
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
class DirectivesTransformer(converter.Base):
|
| 87 |
+
"""Parses compiler directives and converts them into AST annotations."""
|
| 88 |
+
|
| 89 |
+
def _process_symbol_directive(self, call_node, directive):
|
| 90 |
+
if len(call_node.args) < 1:
|
| 91 |
+
raise ValueError('"%s" requires a positional first argument'
|
| 92 |
+
' as the target' % directive.__name__)
|
| 93 |
+
target = call_node.args[0]
|
| 94 |
+
defs = anno.getanno(target, anno.Static.ORIG_DEFINITIONS)
|
| 95 |
+
for def_ in defs:
|
| 96 |
+
def_.directives[directive] = _map_args(call_node, directive)
|
| 97 |
+
return call_node
|
| 98 |
+
|
| 99 |
+
def _process_statement_directive(self, call_node, directive):
|
| 100 |
+
if self.state[_LoopScope].statements_visited > 1:
|
| 101 |
+
raise ValueError(
|
| 102 |
+
'"%s" must be the first statement in the loop block' % (
|
| 103 |
+
directive.__name__))
|
| 104 |
+
if self.state[_LoopScope].level < 2:
|
| 105 |
+
raise ValueError(
|
| 106 |
+
'"%s" must be used inside a statement' % directive.__name__)
|
| 107 |
+
target = self.state[_LoopScope].ast_node
|
| 108 |
+
node_anno = anno.getanno(target, anno.Basic.DIRECTIVES, {})
|
| 109 |
+
node_anno[directive] = _map_args(call_node, directive)
|
| 110 |
+
anno.setanno(target, anno.Basic.DIRECTIVES, node_anno)
|
| 111 |
+
return call_node
|
| 112 |
+
|
| 113 |
+
def visit_Name(self, node):
|
| 114 |
+
node = self.generic_visit(node)
|
| 115 |
+
if isinstance(node.ctx, gast.Load):
|
| 116 |
+
defs = anno.getanno(node, anno.Static.DEFINITIONS, ())
|
| 117 |
+
is_defined = bool(defs)
|
| 118 |
+
if not is_defined and node.id in self.ctx.info.namespace:
|
| 119 |
+
anno.setanno(node, STATIC_VALUE, self.ctx.info.namespace[node.id])
|
| 120 |
+
return node
|
| 121 |
+
|
| 122 |
+
def visit_Attribute(self, node):
|
| 123 |
+
node = self.generic_visit(node)
|
| 124 |
+
parent_val = anno.getanno(node.value, STATIC_VALUE, default=None)
|
| 125 |
+
if parent_val is not None and inspect.ismodule(parent_val):
|
| 126 |
+
if hasattr(parent_val, node.attr):
|
| 127 |
+
anno.setanno(node, STATIC_VALUE, getattr(parent_val, node.attr))
|
| 128 |
+
return node
|
| 129 |
+
|
| 130 |
+
def visit_Assign(self, node):
|
| 131 |
+
self.state[_LoopScope].statements_visited += 1
|
| 132 |
+
return self.generic_visit(node)
|
| 133 |
+
|
| 134 |
+
def visit_AugAssign(self, node):
|
| 135 |
+
self.state[_LoopScope].statements_visited += 1
|
| 136 |
+
return self.generic_visit(node)
|
| 137 |
+
|
| 138 |
+
def visit_Expr(self, node):
|
| 139 |
+
self.state[_LoopScope].statements_visited += 1
|
| 140 |
+
node = self.generic_visit(node)
|
| 141 |
+
if isinstance(node.value, gast.Call):
|
| 142 |
+
call_node = node.value
|
| 143 |
+
static_val = anno.getanno(call_node.func, STATIC_VALUE, default=None)
|
| 144 |
+
if static_val is not None:
|
| 145 |
+
# Note: directive calls are not output in the generated code, hence
|
| 146 |
+
# the removal from the code by returning None.
|
| 147 |
+
|
| 148 |
+
if static_val is directives.set_element_type:
|
| 149 |
+
self._process_symbol_directive(call_node, static_val)
|
| 150 |
+
return None
|
| 151 |
+
elif static_val is directives.set_loop_options:
|
| 152 |
+
self._process_statement_directive(call_node, static_val)
|
| 153 |
+
return None
|
| 154 |
+
return node
|
| 155 |
+
|
| 156 |
+
# TODO(mdan): This will be insufficient for other control flow.
|
| 157 |
+
# That means that if we ever have a directive that affects things other than
|
| 158 |
+
# loops, we'll need support for parallel scopes, or have multiple converters.
|
| 159 |
+
def _track_and_visit_loop(self, node):
|
| 160 |
+
self.state[_LoopScope].enter()
|
| 161 |
+
self.state[_LoopScope].ast_node = node
|
| 162 |
+
node = self.generic_visit(node)
|
| 163 |
+
# Edge case: a loop with just one directive statement would become empty.
|
| 164 |
+
if not node.body:
|
| 165 |
+
node.body = [gast.Pass()]
|
| 166 |
+
self.state[_LoopScope].exit()
|
| 167 |
+
return node
|
| 168 |
+
|
| 169 |
+
def visit_While(self, node):
|
| 170 |
+
return self._track_and_visit_loop(node)
|
| 171 |
+
|
| 172 |
+
def visit_For(self, node):
|
| 173 |
+
return self._track_and_visit_loop(node)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def transform(node, ctx):
|
| 177 |
+
return DirectivesTransformer(ctx).visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/functions.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converts function definitions and lambdas by adding necessary boilerplate."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import anno
|
| 21 |
+
from tensorflow.python.autograph.pyct import parser
|
| 22 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 23 |
+
from tensorflow.python.autograph.pyct import templates
|
| 24 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 25 |
+
from tensorflow.python.autograph.pyct.static_analysis import annos
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
class _Function(object):
|
| 29 |
+
|
| 30 |
+
def __init__(self):
|
| 31 |
+
self.context_name = None
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class FunctionTransformer(converter.Base):
|
| 35 |
+
"""Wraps function bodies around autograph-specific boilerplate."""
|
| 36 |
+
|
| 37 |
+
def _function_scope_options(self, fn_scope):
|
| 38 |
+
"""Returns the options with which to create function scopes."""
|
| 39 |
+
# Top-level function receive the options that were directly requested.
|
| 40 |
+
# All others receive the options corresponding to a recursive conversion.
|
| 41 |
+
# Note: this mainly controls the user_requested flag, which is important
|
| 42 |
+
# primarily because the FunctionScope context also creates a
|
| 43 |
+
# ControlStatusCtx(autograph=ENABLED) when user_requested is True. See
|
| 44 |
+
# function_wrappers.py.
|
| 45 |
+
if fn_scope.level == 2:
|
| 46 |
+
return self.ctx.user.options
|
| 47 |
+
return self.ctx.user.options.call_options()
|
| 48 |
+
|
| 49 |
+
def visit_Lambda(self, node):
|
| 50 |
+
with self.state[_Function] as fn_scope:
|
| 51 |
+
node = self.generic_visit(node)
|
| 52 |
+
|
| 53 |
+
# TODO(mdan): Fix the tests so that we can always add this decorator.
|
| 54 |
+
if fn_scope.level > 2:
|
| 55 |
+
return templates.replace_as_expression(
|
| 56 |
+
'ag__.autograph_artifact(l)', l=node)
|
| 57 |
+
|
| 58 |
+
scope = anno.getanno(node, anno.Static.SCOPE)
|
| 59 |
+
function_context_name = self.ctx.namer.new_symbol('lscope',
|
| 60 |
+
scope.referenced)
|
| 61 |
+
fn_scope.context_name = function_context_name
|
| 62 |
+
anno.setanno(node, 'function_context_name', function_context_name)
|
| 63 |
+
|
| 64 |
+
template = """
|
| 65 |
+
ag__.with_function_scope(
|
| 66 |
+
lambda function_context: body, function_context_name, options)
|
| 67 |
+
"""
|
| 68 |
+
node.body = templates.replace_as_expression(
|
| 69 |
+
template,
|
| 70 |
+
options=self._function_scope_options(fn_scope).to_ast(),
|
| 71 |
+
function_context=function_context_name,
|
| 72 |
+
function_context_name=gast.Constant(function_context_name, kind=None),
|
| 73 |
+
body=node.body)
|
| 74 |
+
|
| 75 |
+
return node
|
| 76 |
+
|
| 77 |
+
def visit_FunctionDef(self, node):
|
| 78 |
+
with self.state[_Function] as fn_scope:
|
| 79 |
+
scope = anno.getanno(node, annos.NodeAnno.BODY_SCOPE)
|
| 80 |
+
|
| 81 |
+
function_context_name = self.ctx.namer.new_symbol('fscope',
|
| 82 |
+
scope.referenced)
|
| 83 |
+
fn_scope.context_name = function_context_name
|
| 84 |
+
anno.setanno(node, 'function_context_name', function_context_name)
|
| 85 |
+
|
| 86 |
+
node = self.generic_visit(node)
|
| 87 |
+
|
| 88 |
+
if fn_scope.level <= 2:
|
| 89 |
+
# Top-level functions lose their decorator because the conversion is
|
| 90 |
+
# always just-in-time and by the time it happens the decorators are
|
| 91 |
+
# already set to be applied.
|
| 92 |
+
node.decorator_list = []
|
| 93 |
+
else:
|
| 94 |
+
# TODO(mdan): Fix the tests so that we can always add this decorator.
|
| 95 |
+
# Inner functions are converted already, so we insert a decorator to
|
| 96 |
+
# prevent double conversion. Double conversion would work too, but this
|
| 97 |
+
# saves the overhead.
|
| 98 |
+
node.decorator_list.append(
|
| 99 |
+
parser.parse_expression('ag__.autograph_artifact'))
|
| 100 |
+
|
| 101 |
+
docstring_node = None
|
| 102 |
+
if node.body:
|
| 103 |
+
first_statement = node.body[0]
|
| 104 |
+
if (isinstance(first_statement, gast.Expr) and
|
| 105 |
+
isinstance(first_statement.value, gast.Constant)):
|
| 106 |
+
docstring_node = first_statement
|
| 107 |
+
node.body = node.body[1:]
|
| 108 |
+
|
| 109 |
+
template = """
|
| 110 |
+
with ag__.FunctionScope(
|
| 111 |
+
function_name, context_name, options) as function_context:
|
| 112 |
+
body
|
| 113 |
+
"""
|
| 114 |
+
wrapped_body = templates.replace(
|
| 115 |
+
template,
|
| 116 |
+
function_name=gast.Constant(node.name, kind=None),
|
| 117 |
+
context_name=gast.Constant(function_context_name, kind=None),
|
| 118 |
+
options=self._function_scope_options(fn_scope).to_ast(),
|
| 119 |
+
function_context=function_context_name,
|
| 120 |
+
body=node.body)
|
| 121 |
+
|
| 122 |
+
if docstring_node is not None:
|
| 123 |
+
wrapped_body = [docstring_node] + wrapped_body
|
| 124 |
+
|
| 125 |
+
node.body = wrapped_body
|
| 126 |
+
|
| 127 |
+
return node
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def transform(node, ctx):
|
| 131 |
+
node = qual_names.resolve(node)
|
| 132 |
+
node = activity.resolve(node, ctx, None)
|
| 133 |
+
|
| 134 |
+
return FunctionTransformer(ctx).visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/lists.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converter for list operations.
|
| 16 |
+
|
| 17 |
+
This includes converting Python lists to TensorArray/TensorList.
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
# TODO(mdan): Elaborate the logic here.
|
| 21 |
+
# TODO(mdan): Does it even make sense to attempt to try to use TAs?
|
| 22 |
+
# The current rule (always convert to TensorArray) is naive and insufficient.
|
| 23 |
+
# In general, a better mechanism could look like:
|
| 24 |
+
# * convert to TensorList by default
|
| 25 |
+
# * leave as Python list if the user explicitly forbids it
|
| 26 |
+
# * convert to TensorArray only when complete write once behavior can be
|
| 27 |
+
# guaranteed (e.g. list comprehensions)
|
| 28 |
+
|
| 29 |
+
import gast
|
| 30 |
+
|
| 31 |
+
from tensorflow.python.autograph.core import converter
|
| 32 |
+
from tensorflow.python.autograph.lang import directives
|
| 33 |
+
from tensorflow.python.autograph.pyct import anno
|
| 34 |
+
from tensorflow.python.autograph.pyct import parser
|
| 35 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 36 |
+
from tensorflow.python.autograph.pyct import templates
|
| 37 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 38 |
+
from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class _Statement(object):
|
| 42 |
+
|
| 43 |
+
def __init__(self):
|
| 44 |
+
self.pop_uses = None
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class ListTransformer(converter.Base):
|
| 48 |
+
"""Converts lists and related operations to their TF counterpart."""
|
| 49 |
+
|
| 50 |
+
def visit_List(self, node):
|
| 51 |
+
node = self.generic_visit(node)
|
| 52 |
+
template = """
|
| 53 |
+
ag__.new_list(elements)
|
| 54 |
+
"""
|
| 55 |
+
return templates.replace_as_expression(template, elements=node)
|
| 56 |
+
|
| 57 |
+
def _replace_append_call(self, node):
|
| 58 |
+
assert len(node.args) == 1
|
| 59 |
+
assert isinstance(node.func, gast.Attribute)
|
| 60 |
+
template = """
|
| 61 |
+
target = ag__.list_append(target, element)
|
| 62 |
+
"""
|
| 63 |
+
return templates.replace(
|
| 64 |
+
template,
|
| 65 |
+
target=node.func.value,
|
| 66 |
+
element=node.args[0])
|
| 67 |
+
|
| 68 |
+
def _replace_pop_call(self, node):
|
| 69 |
+
# Expressions that use pop() are converted to a statement + expression.
|
| 70 |
+
#
|
| 71 |
+
# For example:
|
| 72 |
+
#
|
| 73 |
+
# print(target.pop())
|
| 74 |
+
#
|
| 75 |
+
# ... is converted to:
|
| 76 |
+
#
|
| 77 |
+
# target, target_pop = ag__.list_pop(target)
|
| 78 |
+
# print(target_pop)
|
| 79 |
+
#
|
| 80 |
+
# Here, we just generate the variable name and swap it in,
|
| 81 |
+
# and _generate_pop_operation will handle the rest.
|
| 82 |
+
#
|
| 83 |
+
# Multiple uses of pop() are allowed:
|
| 84 |
+
#
|
| 85 |
+
# print(tartget.pop(), target.pop())
|
| 86 |
+
# print(tartget.pop().pop())
|
| 87 |
+
#
|
| 88 |
+
assert isinstance(node.func, gast.Attribute)
|
| 89 |
+
scope = anno.getanno(node, NodeAnno.ARGS_SCOPE)
|
| 90 |
+
target_node = node.func.value
|
| 91 |
+
|
| 92 |
+
# Attempt to use a related name if one exists. Otherwise use something
|
| 93 |
+
# generic.
|
| 94 |
+
if anno.hasanno(target_node, anno.Basic.QN):
|
| 95 |
+
target_name = anno.getanno(target_node, anno.Basic.QN).ssf()
|
| 96 |
+
else:
|
| 97 |
+
target_name = 'list_'
|
| 98 |
+
pop_var_name = self.ctx.namer.new_symbol(target_name, scope.referenced)
|
| 99 |
+
|
| 100 |
+
stmt = self.state[_Statement]
|
| 101 |
+
if stmt.pop_uses is None:
|
| 102 |
+
stmt.pop_uses = []
|
| 103 |
+
stmt.pop_uses.append((node, pop_var_name))
|
| 104 |
+
|
| 105 |
+
return templates.replace_as_expression('var_name', var_name=pop_var_name)
|
| 106 |
+
|
| 107 |
+
def _replace_stack_call(self, node):
|
| 108 |
+
assert len(node.args) == 1
|
| 109 |
+
dtype = self.get_definition_directive(
|
| 110 |
+
node.args[0],
|
| 111 |
+
directives.set_element_type,
|
| 112 |
+
'dtype',
|
| 113 |
+
default=templates.replace_as_expression('None'))
|
| 114 |
+
template = """
|
| 115 |
+
ag__.list_stack(
|
| 116 |
+
target,
|
| 117 |
+
opts=ag__.ListStackOpts(
|
| 118 |
+
element_dtype=dtype,
|
| 119 |
+
original_call=orig_call))
|
| 120 |
+
"""
|
| 121 |
+
return templates.replace_as_expression(
|
| 122 |
+
template,
|
| 123 |
+
dtype=dtype,
|
| 124 |
+
target=node.args[0],
|
| 125 |
+
orig_call=node.func)
|
| 126 |
+
|
| 127 |
+
def visit_Call(self, node):
|
| 128 |
+
node = self.generic_visit(node)
|
| 129 |
+
|
| 130 |
+
# TODO(mdan): This is insufficient if target is a function argument.
|
| 131 |
+
# In the case of function arguments, we need to add the list to the
|
| 132 |
+
# function's return value, because it is being modified.
|
| 133 |
+
# TODO(mdan): Checking just the name is brittle, can it be improved?
|
| 134 |
+
if isinstance(node.func, gast.Attribute):
|
| 135 |
+
func_name = node.func.attr
|
| 136 |
+
if func_name == 'append' and (len(node.args) == 1):
|
| 137 |
+
node = self._replace_append_call(node)
|
| 138 |
+
elif func_name == 'pop' and (len(node.args) <= 1):
|
| 139 |
+
node = self._replace_pop_call(node)
|
| 140 |
+
elif (func_name == 'stack' and (len(node.args) == 1) and
|
| 141 |
+
(not node.keywords or node.keywords[0].arg == 'strict')):
|
| 142 |
+
# This avoids false positives with keyword args.
|
| 143 |
+
# TODO(mdan): handle kwargs properly.
|
| 144 |
+
node = self._replace_stack_call(node)
|
| 145 |
+
|
| 146 |
+
return node
|
| 147 |
+
|
| 148 |
+
def _generate_pop_operation(self, original_call_node, pop_var_name):
|
| 149 |
+
assert isinstance(original_call_node.func, gast.Attribute)
|
| 150 |
+
|
| 151 |
+
if original_call_node.args:
|
| 152 |
+
pop_element = original_call_node.args[0]
|
| 153 |
+
else:
|
| 154 |
+
pop_element = parser.parse_expression('None')
|
| 155 |
+
|
| 156 |
+
# The call will be something like "target.pop()", and the dtype is hooked to
|
| 157 |
+
# target, hence the func.value.
|
| 158 |
+
# TODO(mdan): For lists of lists, this won't work.
|
| 159 |
+
# The reason why it won't work is because it's unclear how to annotate
|
| 160 |
+
# the list as a "list of lists with a certain element type" when using
|
| 161 |
+
# operations like `l.pop().pop()`.
|
| 162 |
+
dtype = self.get_definition_directive(
|
| 163 |
+
original_call_node.func.value,
|
| 164 |
+
directives.set_element_type,
|
| 165 |
+
'dtype',
|
| 166 |
+
default=templates.replace_as_expression('None'))
|
| 167 |
+
shape = self.get_definition_directive(
|
| 168 |
+
original_call_node.func.value,
|
| 169 |
+
directives.set_element_type,
|
| 170 |
+
'shape',
|
| 171 |
+
default=templates.replace_as_expression('None'))
|
| 172 |
+
|
| 173 |
+
template = """
|
| 174 |
+
target, pop_var_name = ag__.list_pop(
|
| 175 |
+
target, element,
|
| 176 |
+
opts=ag__.ListPopOpts(element_dtype=dtype, element_shape=shape))
|
| 177 |
+
"""
|
| 178 |
+
return templates.replace(
|
| 179 |
+
template,
|
| 180 |
+
target=original_call_node.func.value,
|
| 181 |
+
pop_var_name=pop_var_name,
|
| 182 |
+
element=pop_element,
|
| 183 |
+
dtype=dtype,
|
| 184 |
+
shape=shape)
|
| 185 |
+
|
| 186 |
+
def _postprocess_statement(self, node):
|
| 187 |
+
"""Inserts any separate pop() calls that node may use."""
|
| 188 |
+
pop_uses = self.state[_Statement].pop_uses
|
| 189 |
+
if pop_uses:
|
| 190 |
+
replacements = []
|
| 191 |
+
for original_call_node, pop_var_name in pop_uses:
|
| 192 |
+
replacements.extend(
|
| 193 |
+
self._generate_pop_operation(original_call_node, pop_var_name))
|
| 194 |
+
replacements.append(node)
|
| 195 |
+
node = replacements
|
| 196 |
+
self.state[_Statement].exit()
|
| 197 |
+
return node, None
|
| 198 |
+
|
| 199 |
+
def _visit_and_process_block(self, block):
|
| 200 |
+
return self.visit_block(
|
| 201 |
+
block,
|
| 202 |
+
before_visit=self.state[_Statement].enter,
|
| 203 |
+
after_visit=self._postprocess_statement)
|
| 204 |
+
|
| 205 |
+
def visit_FunctionDef(self, node):
|
| 206 |
+
node.args = self.generic_visit(node.args)
|
| 207 |
+
node.decorator_list = self.visit_block(node.decorator_list)
|
| 208 |
+
node.body = self._visit_and_process_block(node.body)
|
| 209 |
+
return node
|
| 210 |
+
|
| 211 |
+
def visit_For(self, node):
|
| 212 |
+
node.target = self.visit(node.target)
|
| 213 |
+
node.body = self._visit_and_process_block(node.body)
|
| 214 |
+
node.orelse = self._visit_and_process_block(node.orelse)
|
| 215 |
+
return node
|
| 216 |
+
|
| 217 |
+
def visit_While(self, node):
|
| 218 |
+
node.test = self.visit(node.test)
|
| 219 |
+
node.body = self._visit_and_process_block(node.body)
|
| 220 |
+
node.orelse = self._visit_and_process_block(node.orelse)
|
| 221 |
+
return node
|
| 222 |
+
|
| 223 |
+
def visit_If(self, node):
|
| 224 |
+
node.test = self.visit(node.test)
|
| 225 |
+
node.body = self._visit_and_process_block(node.body)
|
| 226 |
+
node.orelse = self._visit_and_process_block(node.orelse)
|
| 227 |
+
return node
|
| 228 |
+
|
| 229 |
+
def visit_With(self, node):
|
| 230 |
+
node.items = self.visit_block(node.items)
|
| 231 |
+
node.body = self._visit_and_process_block(node.body)
|
| 232 |
+
return node
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
def transform(node, ctx):
|
| 236 |
+
node = qual_names.resolve(node)
|
| 237 |
+
node = activity.resolve(node, ctx, None)
|
| 238 |
+
|
| 239 |
+
return ListTransformer(ctx).visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/logical_expressions.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converter for logical expressions, e.g. `a and b -> tf.logical_and(a, b)`."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import parser
|
| 21 |
+
from tensorflow.python.autograph.pyct import templates
|
| 22 |
+
|
| 23 |
+
# TODO(mdan): Properly extract boolean ops according to lazy eval rules.
|
| 24 |
+
# Note that this isn't completely safe either, because tensors may have control
|
| 25 |
+
# dependencies.
|
| 26 |
+
# Note that for loops that should be done after the loop was converted to
|
| 27 |
+
# tf.while_loop so that the expanded conditionals are properly scoped.
|
| 28 |
+
|
| 29 |
+
# Used to signal that an operand is safe for non-lazy evaluation.
|
| 30 |
+
SAFE_BOOLEAN_OPERAND = 'SAFE_BOOLEAN_OPERAND'
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
LOGICAL_OPERATORS = {
|
| 34 |
+
gast.And: 'ag__.and_',
|
| 35 |
+
gast.Not: 'ag__.not_',
|
| 36 |
+
gast.Or: 'ag__.or_',
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
EQUALITY_OPERATORS = {
|
| 40 |
+
gast.Eq: 'ag__.eq',
|
| 41 |
+
gast.NotEq: 'ag__.not_eq',
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class LogicalExpressionTransformer(converter.Base):
|
| 46 |
+
"""Converts logical expressions to corresponding TF calls."""
|
| 47 |
+
|
| 48 |
+
def _overload_of(self, operator):
|
| 49 |
+
op_type = type(operator)
|
| 50 |
+
if op_type in LOGICAL_OPERATORS:
|
| 51 |
+
return LOGICAL_OPERATORS[op_type]
|
| 52 |
+
if self.ctx.user.options.uses(converter.Feature.EQUALITY_OPERATORS):
|
| 53 |
+
if op_type in EQUALITY_OPERATORS:
|
| 54 |
+
return EQUALITY_OPERATORS[op_type]
|
| 55 |
+
return None
|
| 56 |
+
|
| 57 |
+
def _as_lambda(self, expr):
|
| 58 |
+
return templates.replace_as_expression('lambda: expr', expr=expr)
|
| 59 |
+
|
| 60 |
+
def _as_binary_function(self, func_name, arg1, arg2):
|
| 61 |
+
return templates.replace_as_expression(
|
| 62 |
+
'func_name(arg1, arg2)',
|
| 63 |
+
func_name=parser.parse_expression(func_name),
|
| 64 |
+
arg1=arg1,
|
| 65 |
+
arg2=arg2)
|
| 66 |
+
|
| 67 |
+
def _as_binary_operation(self, op, arg1, arg2):
|
| 68 |
+
template = templates.replace_as_expression(
|
| 69 |
+
'arg1 is arg2', # Note: `is` will be replaced with `op` below.
|
| 70 |
+
arg1=arg1,
|
| 71 |
+
arg2=arg2)
|
| 72 |
+
template.ops[0] = op
|
| 73 |
+
return template
|
| 74 |
+
|
| 75 |
+
def _as_unary_function(self, func_name, arg):
|
| 76 |
+
return templates.replace_as_expression(
|
| 77 |
+
'func_name(arg)', func_name=parser.parse_expression(func_name), arg=arg)
|
| 78 |
+
|
| 79 |
+
def _process_binop(self, op, left, right):
|
| 80 |
+
overload = self._overload_of(op)
|
| 81 |
+
if overload is None:
|
| 82 |
+
return self._as_binary_operation(op, left, right)
|
| 83 |
+
return self._as_binary_function(overload, left, right)
|
| 84 |
+
|
| 85 |
+
def visit_Compare(self, node):
|
| 86 |
+
node = self.generic_visit(node)
|
| 87 |
+
|
| 88 |
+
ops_and_comps = list(zip(node.ops, node.comparators))
|
| 89 |
+
left = node.left
|
| 90 |
+
|
| 91 |
+
# Repeated comparisons are converted to conjunctions:
|
| 92 |
+
# a < b < c -> a < b and b < c
|
| 93 |
+
op_tree = None
|
| 94 |
+
while ops_and_comps:
|
| 95 |
+
op, right = ops_and_comps.pop(0)
|
| 96 |
+
binary_comparison = self._process_binop(op, left, right)
|
| 97 |
+
if op_tree is not None:
|
| 98 |
+
op_tree = self._as_binary_function('ag__.and_',
|
| 99 |
+
self._as_lambda(op_tree),
|
| 100 |
+
self._as_lambda(binary_comparison))
|
| 101 |
+
else:
|
| 102 |
+
op_tree = binary_comparison
|
| 103 |
+
left = right
|
| 104 |
+
|
| 105 |
+
assert op_tree is not None
|
| 106 |
+
return op_tree
|
| 107 |
+
|
| 108 |
+
def visit_UnaryOp(self, node):
|
| 109 |
+
node = self.generic_visit(node)
|
| 110 |
+
|
| 111 |
+
overload = self._overload_of(node.op)
|
| 112 |
+
if overload is None:
|
| 113 |
+
return node
|
| 114 |
+
|
| 115 |
+
return self._as_unary_function(overload, node.operand)
|
| 116 |
+
|
| 117 |
+
def visit_BoolOp(self, node):
|
| 118 |
+
node = self.generic_visit(node)
|
| 119 |
+
node_values = node.values
|
| 120 |
+
right = node.values.pop()
|
| 121 |
+
while node_values:
|
| 122 |
+
left = node_values.pop()
|
| 123 |
+
right = self._as_binary_function(
|
| 124 |
+
self._overload_of(node.op), self._as_lambda(left),
|
| 125 |
+
self._as_lambda(right))
|
| 126 |
+
return right
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def transform(node, ctx):
|
| 130 |
+
transformer = LogicalExpressionTransformer(ctx)
|
| 131 |
+
return transformer.visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/return_statements.py
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Canonicalizes functions with multiple returns to use just one."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import anno
|
| 21 |
+
from tensorflow.python.autograph.pyct import parser
|
| 22 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 23 |
+
from tensorflow.python.autograph.pyct import templates
|
| 24 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 25 |
+
from tensorflow.python.autograph.pyct.static_analysis.annos import NodeAnno
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
BODY_DEFINITELY_RETURNS = 'BODY_DEFINITELY_RETURNS'
|
| 29 |
+
ORELSE_DEFINITELY_RETURNS = 'ORELSE_DEFINITELY_RETURNS'
|
| 30 |
+
STMT_DEFINITELY_RETURNS = 'STMT_DEFINITELY_RETURNS'
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class _RewriteBlock(object):
|
| 34 |
+
|
| 35 |
+
def __init__(self):
|
| 36 |
+
self.definitely_returns = False
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
class ConditionalReturnRewriter(converter.Base):
|
| 40 |
+
"""Rewrites a pattern where it's unobvious that all paths return a value.
|
| 41 |
+
|
| 42 |
+
This rewrite allows avoiding intermediate None return values.
|
| 43 |
+
|
| 44 |
+
The following pattern:
|
| 45 |
+
|
| 46 |
+
if cond:
|
| 47 |
+
<block 1>
|
| 48 |
+
return
|
| 49 |
+
else:
|
| 50 |
+
<block 2>
|
| 51 |
+
<block 3>
|
| 52 |
+
|
| 53 |
+
is converted to:
|
| 54 |
+
|
| 55 |
+
if cond:
|
| 56 |
+
<block 1>
|
| 57 |
+
return
|
| 58 |
+
else:
|
| 59 |
+
<block 2>
|
| 60 |
+
<block 3>
|
| 61 |
+
|
| 62 |
+
and vice-versa (if the else returns, subsequent statements are moved under the
|
| 63 |
+
if branch).
|
| 64 |
+
"""
|
| 65 |
+
|
| 66 |
+
def visit_Return(self, node):
|
| 67 |
+
self.state[_RewriteBlock].definitely_returns = True
|
| 68 |
+
return node
|
| 69 |
+
|
| 70 |
+
def _postprocess_statement(self, node):
|
| 71 |
+
# If the node definitely returns (e.g. it's a with statement with a
|
| 72 |
+
# return statement in it), then the current block also definitely returns.
|
| 73 |
+
if anno.getanno(node, STMT_DEFINITELY_RETURNS, default=False):
|
| 74 |
+
self.state[_RewriteBlock].definitely_returns = True
|
| 75 |
+
|
| 76 |
+
# The special case: collapse a typical conditional return pattern into
|
| 77 |
+
# a single conditional with possibly returns on both branches. This
|
| 78 |
+
# reduces the use of None return values, which don't work with TF
|
| 79 |
+
# conditionals.
|
| 80 |
+
if (isinstance(node, gast.If)
|
| 81 |
+
and anno.getanno(node, BODY_DEFINITELY_RETURNS, default=False)):
|
| 82 |
+
return node, node.orelse
|
| 83 |
+
elif (isinstance(node, gast.If)
|
| 84 |
+
and anno.getanno(node, ORELSE_DEFINITELY_RETURNS, default=False)):
|
| 85 |
+
return node, node.body
|
| 86 |
+
|
| 87 |
+
return node, None
|
| 88 |
+
|
| 89 |
+
def _visit_statement_block(self, node, nodes):
|
| 90 |
+
self.state[_RewriteBlock].enter()
|
| 91 |
+
new_nodes = self.visit_block(nodes, after_visit=self._postprocess_statement)
|
| 92 |
+
block_definitely_returns = self.state[_RewriteBlock].definitely_returns
|
| 93 |
+
self.state[_RewriteBlock].exit()
|
| 94 |
+
return new_nodes, block_definitely_returns
|
| 95 |
+
|
| 96 |
+
def visit_While(self, node):
|
| 97 |
+
node.test = self.visit(node.test)
|
| 98 |
+
node.body, _ = self._visit_statement_block(node, node.body)
|
| 99 |
+
node.orelse, _ = self._visit_statement_block(node, node.orelse)
|
| 100 |
+
return node
|
| 101 |
+
|
| 102 |
+
def visit_For(self, node):
|
| 103 |
+
node.iter = self.visit(node.iter)
|
| 104 |
+
node.target = self.visit(node.target)
|
| 105 |
+
node.body, _ = self._visit_statement_block(node, node.body)
|
| 106 |
+
node.orelse, _ = self._visit_statement_block(node, node.orelse)
|
| 107 |
+
return node
|
| 108 |
+
|
| 109 |
+
def visit_With(self, node):
|
| 110 |
+
node.items = self.visit_block(node.items)
|
| 111 |
+
node.body, definitely_returns = self._visit_statement_block(node, node.body)
|
| 112 |
+
if definitely_returns:
|
| 113 |
+
anno.setanno(node, STMT_DEFINITELY_RETURNS, True)
|
| 114 |
+
return node
|
| 115 |
+
|
| 116 |
+
def visit_Try(self, node):
|
| 117 |
+
# We could decide whether a 'try' DEFINITELY_RETURNS based on its components
|
| 118 |
+
# It is not clear whether we want to do anything with this given
|
| 119 |
+
# a 'try' is likely to throw an exception in some circumstances.
|
| 120 |
+
node.body, _ = self._visit_statement_block(node, node.body)
|
| 121 |
+
node.orelse, _ = self._visit_statement_block(node, node.orelse)
|
| 122 |
+
node.finalbody, _ = self._visit_statement_block(node, node.finalbody)
|
| 123 |
+
node.handlers = self.visit_block(node.handlers)
|
| 124 |
+
return node
|
| 125 |
+
|
| 126 |
+
def visit_ExceptHandler(self, node):
|
| 127 |
+
# To determine whether `try` DEFINITELY_RETURNS we need to revisit this.
|
| 128 |
+
node.body, _ = self._visit_statement_block(node, node.body)
|
| 129 |
+
return node
|
| 130 |
+
|
| 131 |
+
def visit_If(self, node):
|
| 132 |
+
node.test = self.visit(node.test)
|
| 133 |
+
|
| 134 |
+
node.body, body_definitely_returns = self._visit_statement_block(
|
| 135 |
+
node, node.body)
|
| 136 |
+
if body_definitely_returns:
|
| 137 |
+
anno.setanno(node, BODY_DEFINITELY_RETURNS, True)
|
| 138 |
+
|
| 139 |
+
node.orelse, orelse_definitely_returns = self._visit_statement_block(
|
| 140 |
+
node, node.orelse)
|
| 141 |
+
if orelse_definitely_returns:
|
| 142 |
+
anno.setanno(node, ORELSE_DEFINITELY_RETURNS, True)
|
| 143 |
+
|
| 144 |
+
if body_definitely_returns and orelse_definitely_returns:
|
| 145 |
+
self.state[_RewriteBlock].definitely_returns = True
|
| 146 |
+
|
| 147 |
+
return node
|
| 148 |
+
|
| 149 |
+
def visit_FunctionDef(self, node):
|
| 150 |
+
node.args = self.visit(node.args)
|
| 151 |
+
node.body, _ = self._visit_statement_block(node, node.body)
|
| 152 |
+
return node
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
class _Block(object):
|
| 156 |
+
|
| 157 |
+
def __init__(self):
|
| 158 |
+
self.is_function = False
|
| 159 |
+
self.return_used = False
|
| 160 |
+
self.create_guard_next = False
|
| 161 |
+
self.create_guard_now = False
|
| 162 |
+
|
| 163 |
+
def __repr__(self):
|
| 164 |
+
return 'used: {}'.format(
|
| 165 |
+
self.return_used)
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
class _Function(object):
|
| 169 |
+
|
| 170 |
+
def __init__(self):
|
| 171 |
+
self.do_return_var_name = None
|
| 172 |
+
self.retval_var_name = None
|
| 173 |
+
|
| 174 |
+
def __repr__(self):
|
| 175 |
+
return 'return control: {}, return value: {}'.format(
|
| 176 |
+
self.do_return_var_name, self.retval_var_name)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
class ReturnStatementsTransformer(converter.Base):
|
| 180 |
+
"""Lowers return statements into variables and conditionals.
|
| 181 |
+
|
| 182 |
+
Specifically, the following pattern:
|
| 183 |
+
|
| 184 |
+
<block 1>
|
| 185 |
+
return val
|
| 186 |
+
<block 2>
|
| 187 |
+
|
| 188 |
+
is converted to:
|
| 189 |
+
|
| 190 |
+
do_return = False
|
| 191 |
+
retval = None
|
| 192 |
+
|
| 193 |
+
<block 1>
|
| 194 |
+
|
| 195 |
+
do_return = True
|
| 196 |
+
retval = val
|
| 197 |
+
|
| 198 |
+
if not do_return:
|
| 199 |
+
<block 2>
|
| 200 |
+
|
| 201 |
+
return retval
|
| 202 |
+
|
| 203 |
+
The conversion adjusts loops as well:
|
| 204 |
+
|
| 205 |
+
<block 1>
|
| 206 |
+
while cond:
|
| 207 |
+
<block 2>
|
| 208 |
+
return retval
|
| 209 |
+
|
| 210 |
+
is converted to:
|
| 211 |
+
|
| 212 |
+
<block 1>
|
| 213 |
+
while not do_return and cond:
|
| 214 |
+
<block 2>
|
| 215 |
+
do_return = True
|
| 216 |
+
retval = val
|
| 217 |
+
"""
|
| 218 |
+
|
| 219 |
+
def __init__(self, ctx, allow_missing_return):
|
| 220 |
+
super(ReturnStatementsTransformer, self).__init__(ctx)
|
| 221 |
+
self.allow_missing_return = allow_missing_return
|
| 222 |
+
|
| 223 |
+
def visit_Return(self, node):
|
| 224 |
+
for block in reversed(self.state[_Block].stack):
|
| 225 |
+
block.return_used = True
|
| 226 |
+
block.create_guard_next = True
|
| 227 |
+
if block.is_function:
|
| 228 |
+
break
|
| 229 |
+
|
| 230 |
+
retval = node.value if node.value else parser.parse_expression('None')
|
| 231 |
+
|
| 232 |
+
# Note: If `return <expr> raises, then the return is aborted.
|
| 233 |
+
# The try-catch below ensures the variables remain consistent in that case.
|
| 234 |
+
template = """
|
| 235 |
+
try:
|
| 236 |
+
do_return_var_name = True
|
| 237 |
+
retval_var_name = retval
|
| 238 |
+
except:
|
| 239 |
+
do_return_var_name = False
|
| 240 |
+
raise
|
| 241 |
+
"""
|
| 242 |
+
node = templates.replace(
|
| 243 |
+
template,
|
| 244 |
+
do_return_var_name=self.state[_Function].do_return_var_name,
|
| 245 |
+
retval_var_name=self.state[_Function].retval_var_name,
|
| 246 |
+
retval=retval)
|
| 247 |
+
|
| 248 |
+
return node
|
| 249 |
+
|
| 250 |
+
def _postprocess_statement(self, node):
|
| 251 |
+
if not self.state[_Block].return_used:
|
| 252 |
+
return node, None
|
| 253 |
+
|
| 254 |
+
state = self.state[_Block]
|
| 255 |
+
if state.create_guard_now:
|
| 256 |
+
template = """
|
| 257 |
+
if not do_return_var_name:
|
| 258 |
+
original_node
|
| 259 |
+
"""
|
| 260 |
+
cond, = templates.replace(
|
| 261 |
+
template,
|
| 262 |
+
do_return_var_name=self.state[_Function].do_return_var_name,
|
| 263 |
+
original_node=node)
|
| 264 |
+
node, block = cond, cond.body
|
| 265 |
+
else:
|
| 266 |
+
node, block = node, None
|
| 267 |
+
|
| 268 |
+
state.create_guard_now = state.create_guard_next
|
| 269 |
+
state.create_guard_next = False
|
| 270 |
+
|
| 271 |
+
return node, block
|
| 272 |
+
|
| 273 |
+
def _visit_statement_block(self, node, nodes):
|
| 274 |
+
self.state[_Block].enter()
|
| 275 |
+
nodes = self.visit_block(nodes, after_visit=self._postprocess_statement)
|
| 276 |
+
self.state[_Block].exit()
|
| 277 |
+
return nodes
|
| 278 |
+
|
| 279 |
+
def visit_While(self, node):
|
| 280 |
+
node.test = self.visit(node.test)
|
| 281 |
+
|
| 282 |
+
# Add the check for return to the loop condition.
|
| 283 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 284 |
+
if self.state[_Block].return_used:
|
| 285 |
+
node.test = templates.replace_as_expression(
|
| 286 |
+
'not control_var and test',
|
| 287 |
+
test=node.test,
|
| 288 |
+
control_var=self.state[_Function].do_return_var_name)
|
| 289 |
+
|
| 290 |
+
node.orelse = self._visit_statement_block(node, node.orelse)
|
| 291 |
+
return node
|
| 292 |
+
|
| 293 |
+
def visit_For(self, node):
|
| 294 |
+
node.iter = self.visit(node.iter)
|
| 295 |
+
node.target = self.visit(node.target)
|
| 296 |
+
|
| 297 |
+
# Add the check for return to the loop condition.
|
| 298 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 299 |
+
if self.state[_Block].return_used:
|
| 300 |
+
extra_test = anno.getanno(node, anno.Basic.EXTRA_LOOP_TEST, default=None)
|
| 301 |
+
if extra_test is not None:
|
| 302 |
+
extra_test = templates.replace_as_expression(
|
| 303 |
+
'not control_var and extra_test',
|
| 304 |
+
extra_test=extra_test,
|
| 305 |
+
control_var=self.state[_Function].do_return_var_name)
|
| 306 |
+
else:
|
| 307 |
+
extra_test = templates.replace_as_expression(
|
| 308 |
+
'not control_var',
|
| 309 |
+
control_var=self.state[_Function].do_return_var_name)
|
| 310 |
+
anno.setanno(node, anno.Basic.EXTRA_LOOP_TEST, extra_test)
|
| 311 |
+
|
| 312 |
+
node.orelse = self._visit_statement_block(node, node.orelse)
|
| 313 |
+
return node
|
| 314 |
+
|
| 315 |
+
def visit_With(self, node):
|
| 316 |
+
node.items = self.visit_block(node.items)
|
| 317 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 318 |
+
return node
|
| 319 |
+
|
| 320 |
+
def visit_Try(self, node):
|
| 321 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 322 |
+
node.orelse = self._visit_statement_block(node, node.orelse)
|
| 323 |
+
node.finalbody = self._visit_statement_block(node, node.finalbody)
|
| 324 |
+
node.handlers = self.visit_block(node.handlers)
|
| 325 |
+
return node
|
| 326 |
+
|
| 327 |
+
def visit_ExceptHandler(self, node):
|
| 328 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 329 |
+
return node
|
| 330 |
+
|
| 331 |
+
def visit_If(self, node):
|
| 332 |
+
node.test = self.visit(node.test)
|
| 333 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 334 |
+
node.orelse = self._visit_statement_block(node, node.orelse)
|
| 335 |
+
return node
|
| 336 |
+
|
| 337 |
+
def visit_FunctionDef(self, node):
|
| 338 |
+
with self.state[_Function] as fn:
|
| 339 |
+
with self.state[_Block] as block:
|
| 340 |
+
block.is_function = True
|
| 341 |
+
|
| 342 |
+
scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
|
| 343 |
+
do_return_var_name = self.ctx.namer.new_symbol('do_return',
|
| 344 |
+
scope.referenced)
|
| 345 |
+
retval_var_name = self.ctx.namer.new_symbol('retval_', scope.referenced)
|
| 346 |
+
fn.do_return_var_name = do_return_var_name
|
| 347 |
+
fn.retval_var_name = retval_var_name
|
| 348 |
+
|
| 349 |
+
node.body = self._visit_statement_block(node, node.body)
|
| 350 |
+
|
| 351 |
+
if block.return_used:
|
| 352 |
+
|
| 353 |
+
if self.allow_missing_return:
|
| 354 |
+
# The function would have a single `with` node that wraps the
|
| 355 |
+
# entire body. If the function had a docstring, the body has two
|
| 356 |
+
# nodes, with the `with` as the second node.
|
| 357 |
+
wrapper_node = node.body[-1]
|
| 358 |
+
assert isinstance(wrapper_node, gast.With), (
|
| 359 |
+
'This transformer requires the functions converter.')
|
| 360 |
+
|
| 361 |
+
template = """
|
| 362 |
+
do_return_var_name = False
|
| 363 |
+
retval_var_name = ag__.UndefinedReturnValue()
|
| 364 |
+
body
|
| 365 |
+
return function_context.ret(retval_var_name, do_return_var_name)
|
| 366 |
+
"""
|
| 367 |
+
|
| 368 |
+
wrapper_node.body = templates.replace(
|
| 369 |
+
template,
|
| 370 |
+
body=wrapper_node.body,
|
| 371 |
+
do_return_var_name=do_return_var_name,
|
| 372 |
+
function_context=anno.getanno(node, 'function_context_name'),
|
| 373 |
+
retval_var_name=retval_var_name)
|
| 374 |
+
else:
|
| 375 |
+
template = """
|
| 376 |
+
body
|
| 377 |
+
return retval_var_name
|
| 378 |
+
"""
|
| 379 |
+
node.body = templates.replace(
|
| 380 |
+
template,
|
| 381 |
+
body=node.body,
|
| 382 |
+
do_return_var_name=do_return_var_name,
|
| 383 |
+
retval_var_name=retval_var_name)
|
| 384 |
+
|
| 385 |
+
return node
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
def transform(node, ctx, default_to_null_return=True):
|
| 389 |
+
"""Ensure a function has only a single return, at the end."""
|
| 390 |
+
node = qual_names.resolve(node)
|
| 391 |
+
node = activity.resolve(node, ctx, None)
|
| 392 |
+
|
| 393 |
+
# Note: Technically, these two could be merged into a single walk, but
|
| 394 |
+
# keeping them separate helps with readability.
|
| 395 |
+
node = ConditionalReturnRewriter(ctx).visit(node)
|
| 396 |
+
|
| 397 |
+
node = qual_names.resolve(node)
|
| 398 |
+
node = activity.resolve(node, ctx, None)
|
| 399 |
+
transformer = ReturnStatementsTransformer(
|
| 400 |
+
ctx, allow_missing_return=default_to_null_return)
|
| 401 |
+
node = transformer.visit(node)
|
| 402 |
+
return node
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/slices.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converter for slice operations."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.lang import directives
|
| 21 |
+
from tensorflow.python.autograph.pyct import templates
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class SliceTransformer(converter.Base):
|
| 25 |
+
"""Converts slicing operations to their TF counterpart.
|
| 26 |
+
|
| 27 |
+
Currently, relying on the default slice operator that Tensor uses is
|
| 28 |
+
insufficient, because TensorArray and tensor lists use dedicated index read
|
| 29 |
+
and write functions.
|
| 30 |
+
"""
|
| 31 |
+
|
| 32 |
+
def _process_single_assignment(self, target, value):
|
| 33 |
+
if not isinstance(target, gast.Subscript):
|
| 34 |
+
return None
|
| 35 |
+
s = target.slice
|
| 36 |
+
if isinstance(s, (gast.Tuple, gast.Slice)):
|
| 37 |
+
return None
|
| 38 |
+
|
| 39 |
+
template = """
|
| 40 |
+
target = ag__.set_item(target, key, item)
|
| 41 |
+
"""
|
| 42 |
+
return templates.replace(
|
| 43 |
+
template, target=target.value, key=target.slice, item=value)
|
| 44 |
+
|
| 45 |
+
def visit_Assign(self, node):
|
| 46 |
+
node = self.generic_visit(node)
|
| 47 |
+
# TODO(mdan): Support unpackings and multiple assignments.
|
| 48 |
+
if len(node.targets) != 1:
|
| 49 |
+
raise NotImplementedError('multiple assignment')
|
| 50 |
+
replacement = self._process_single_assignment(node.targets[0], node.value)
|
| 51 |
+
if replacement is not None:
|
| 52 |
+
return replacement
|
| 53 |
+
return node
|
| 54 |
+
|
| 55 |
+
def visit_Subscript(self, node):
|
| 56 |
+
node = self.generic_visit(node)
|
| 57 |
+
s = node.slice
|
| 58 |
+
if isinstance(s, (gast.Tuple, gast.Slice)):
|
| 59 |
+
return node
|
| 60 |
+
|
| 61 |
+
if not isinstance(node.ctx, gast.Load):
|
| 62 |
+
# Index writes are handled at a higher level, one at which the rvalue is
|
| 63 |
+
# also available.
|
| 64 |
+
return node
|
| 65 |
+
|
| 66 |
+
dtype = self.get_definition_directive(
|
| 67 |
+
node.value,
|
| 68 |
+
directives.set_element_type,
|
| 69 |
+
'dtype',
|
| 70 |
+
default=templates.replace_as_expression('None'))
|
| 71 |
+
|
| 72 |
+
template = """
|
| 73 |
+
ag__.get_item(
|
| 74 |
+
target,
|
| 75 |
+
key,
|
| 76 |
+
opts=ag__.GetItemOpts(element_dtype=dtype))
|
| 77 |
+
"""
|
| 78 |
+
return templates.replace_as_expression(
|
| 79 |
+
template, target=node.value, key=s, dtype=dtype)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def transform(node, ctx):
|
| 83 |
+
return SliceTransformer(ctx).visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/converters/variables.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Overloads all variable read operations."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.core import converter
|
| 20 |
+
from tensorflow.python.autograph.pyct import anno
|
| 21 |
+
from tensorflow.python.autograph.pyct import templates
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class VariableAccessTransformer(converter.Base):
|
| 25 |
+
"""Rewrites basic symbol reads.
|
| 26 |
+
|
| 27 |
+
This transformer rewrites variable reads with a "read" operator which allows
|
| 28 |
+
tracking activity.
|
| 29 |
+
|
| 30 |
+
Example:
|
| 31 |
+
|
| 32 |
+
For a basic statement:
|
| 33 |
+
|
| 34 |
+
a = b + c
|
| 35 |
+
|
| 36 |
+
This is translated to:
|
| 37 |
+
|
| 38 |
+
a = ld(b) + ld(c)
|
| 39 |
+
|
| 40 |
+
Augmented assignment operations also introduce a `ld` operator:
|
| 41 |
+
|
| 42 |
+
a += b
|
| 43 |
+
|
| 44 |
+
The assignment target also receives an operator to properly represent the
|
| 45 |
+
read:
|
| 46 |
+
|
| 47 |
+
a = ld(a)
|
| 48 |
+
a += ld(b)
|
| 49 |
+
"""
|
| 50 |
+
|
| 51 |
+
def visit_Name(self, node):
|
| 52 |
+
# Only the loads which existed in the original code are overloaded.
|
| 53 |
+
if not anno.hasanno(node, anno.Static.ORIG_DEFINITIONS):
|
| 54 |
+
return node
|
| 55 |
+
if isinstance(node.ctx, gast.Load):
|
| 56 |
+
node = templates.replace_as_expression('ag__.ld(var_)', var_=node)
|
| 57 |
+
return node
|
| 58 |
+
|
| 59 |
+
def visit_Delete(self, node):
|
| 60 |
+
node = self.generic_visit(node)
|
| 61 |
+
|
| 62 |
+
rewrite_targets = []
|
| 63 |
+
for tgt in node.targets:
|
| 64 |
+
# Don't rewrite composites like `del a[0]`.
|
| 65 |
+
if isinstance(tgt, gast.Name):
|
| 66 |
+
rewrite_targets.append(tgt)
|
| 67 |
+
|
| 68 |
+
if not rewrite_targets:
|
| 69 |
+
return node
|
| 70 |
+
|
| 71 |
+
results = []
|
| 72 |
+
for tgt in rewrite_targets:
|
| 73 |
+
template = """
|
| 74 |
+
var_ = ag__.Undefined(var_name)
|
| 75 |
+
"""
|
| 76 |
+
results.extend(templates.replace(
|
| 77 |
+
template, var_=tgt, var_name=gast.Constant(tgt.id, kind=None)))
|
| 78 |
+
remaining_targets = [n for n in node.targets if n not in rewrite_targets]
|
| 79 |
+
if remaining_targets:
|
| 80 |
+
results.append(gast.Delete(targets=remaining_targets))
|
| 81 |
+
|
| 82 |
+
return results
|
| 83 |
+
|
| 84 |
+
def visit_AugAssign(self, node):
|
| 85 |
+
if isinstance(node.target, gast.Name):
|
| 86 |
+
template = """
|
| 87 |
+
var_ = ag__.ld(var_)
|
| 88 |
+
original
|
| 89 |
+
"""
|
| 90 |
+
node = templates.replace(template, var_=node.target, original=node)
|
| 91 |
+
else:
|
| 92 |
+
node = self.generic_visit(node)
|
| 93 |
+
return node
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def transform(node, ctx):
|
| 97 |
+
return VariableAccessTransformer(ctx).visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__init__.py
ADDED
|
File without changes
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (208 Bytes). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/ag_ctx.cpython-310.pyc
ADDED
|
Binary file (3.54 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config.cpython-310.pyc
ADDED
|
Binary file (873 Bytes). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/config_lib.cpython-310.pyc
ADDED
|
Binary file (1.89 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter.cpython-310.pyc
ADDED
|
Binary file (10.2 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/converter_testing.cpython-310.pyc
ADDED
|
Binary file (3.83 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/function_wrappers.cpython-310.pyc
ADDED
|
Binary file (3.62 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/__pycache__/unsupported_features_checker.cpython-310.pyc
ADDED
|
Binary file (1.92 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/ag_ctx.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Thread-local context managers for AutoGraph."""
|
| 16 |
+
|
| 17 |
+
import enum
|
| 18 |
+
import inspect
|
| 19 |
+
import threading
|
| 20 |
+
|
| 21 |
+
from tensorflow.python.autograph.utils import ag_logging
|
| 22 |
+
from tensorflow.python.util.tf_export import tf_export
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
stacks = threading.local()
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def _control_ctx():
|
| 29 |
+
if not hasattr(stacks, 'control_status'):
|
| 30 |
+
stacks.control_status = [_default_control_status_ctx()]
|
| 31 |
+
return stacks.control_status
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
@tf_export('__internal__.autograph.control_status_ctx', v1=[])
|
| 35 |
+
def control_status_ctx():
|
| 36 |
+
"""Returns the current control context for autograph.
|
| 37 |
+
|
| 38 |
+
This method is useful when calling `tf.__internal__.autograph.tf_convert`,
|
| 39 |
+
The context will be used by tf_convert to determine whether it should convert
|
| 40 |
+
the input function. See the sample usage like below:
|
| 41 |
+
|
| 42 |
+
```
|
| 43 |
+
def foo(func):
|
| 44 |
+
return tf.__internal__.autograph.tf_convert(
|
| 45 |
+
input_fn, ctx=tf.__internal__.autograph.control_status_ctx())()
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
Returns:
|
| 49 |
+
The current control context of autograph.
|
| 50 |
+
"""
|
| 51 |
+
ret = _control_ctx()[-1]
|
| 52 |
+
return ret
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
class Status(enum.Enum):
|
| 56 |
+
UNSPECIFIED = 0
|
| 57 |
+
ENABLED = 1
|
| 58 |
+
DISABLED = 2
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class ControlStatusCtx(object):
|
| 62 |
+
"""A context that tracks whether autograph is enabled by the user."""
|
| 63 |
+
|
| 64 |
+
def __init__(self, status, options=None):
|
| 65 |
+
self.status = status
|
| 66 |
+
self.options = options
|
| 67 |
+
|
| 68 |
+
def __enter__(self):
|
| 69 |
+
_control_ctx().append(self)
|
| 70 |
+
return self
|
| 71 |
+
|
| 72 |
+
def __repr__(self):
|
| 73 |
+
return '{}[status={}, options={}]'.format(
|
| 74 |
+
self.__class__.__name__, self.status, self.options)
|
| 75 |
+
|
| 76 |
+
def __exit__(self, unused_type, unused_value, unused_traceback):
|
| 77 |
+
assert _control_ctx()[-1] is self
|
| 78 |
+
_control_ctx().pop()
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
class NullCtx(object):
|
| 82 |
+
"""Helper substitute for contextlib.nullcontext."""
|
| 83 |
+
|
| 84 |
+
def __enter__(self):
|
| 85 |
+
pass
|
| 86 |
+
|
| 87 |
+
def __exit__(self, unused_type, unused_value, unused_traceback):
|
| 88 |
+
pass
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def _default_control_status_ctx():
|
| 92 |
+
return ControlStatusCtx(status=Status.UNSPECIFIED)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
INSPECT_SOURCE_SUPPORTED = True
|
| 96 |
+
try:
|
| 97 |
+
inspect.getsource(ag_logging.log)
|
| 98 |
+
except OSError:
|
| 99 |
+
INSPECT_SOURCE_SUPPORTED = False
|
| 100 |
+
ag_logging.warning(
|
| 101 |
+
'AutoGraph is not available in this environment: functions lack code'
|
| 102 |
+
' information. This is typical of some environments like the interactive'
|
| 103 |
+
' Python shell. See'
|
| 104 |
+
' https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/g3doc/reference/limitations.md#access-to-source-code'
|
| 105 |
+
' for more information.')
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Global configuration."""
|
| 16 |
+
|
| 17 |
+
from tensorflow.python.autograph.core import config_lib
|
| 18 |
+
|
| 19 |
+
Action = config_lib.Action
|
| 20 |
+
Convert = config_lib.Convert
|
| 21 |
+
DoNotConvert = config_lib.DoNotConvert
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
# This list is evaluated in order and stops at the first rule that tests True
|
| 25 |
+
# for a definitely_convert of definitely_bypass call.
|
| 26 |
+
CONVERSION_RULES = (
|
| 27 |
+
# Known packages
|
| 28 |
+
Convert('tensorflow.python.training.experimental'),
|
| 29 |
+
|
| 30 |
+
# Builtin modules
|
| 31 |
+
DoNotConvert('collections'),
|
| 32 |
+
DoNotConvert('copy'),
|
| 33 |
+
DoNotConvert('cProfile'),
|
| 34 |
+
DoNotConvert('inspect'),
|
| 35 |
+
DoNotConvert('ipdb'),
|
| 36 |
+
DoNotConvert('linecache'),
|
| 37 |
+
DoNotConvert('mock'),
|
| 38 |
+
DoNotConvert('pathlib'),
|
| 39 |
+
DoNotConvert('pdb'),
|
| 40 |
+
DoNotConvert('posixpath'),
|
| 41 |
+
DoNotConvert('pstats'),
|
| 42 |
+
DoNotConvert('re'),
|
| 43 |
+
DoNotConvert('threading'),
|
| 44 |
+
DoNotConvert('urllib'),
|
| 45 |
+
|
| 46 |
+
# Known libraries
|
| 47 |
+
DoNotConvert('matplotlib'),
|
| 48 |
+
DoNotConvert('numpy'),
|
| 49 |
+
DoNotConvert('pandas'),
|
| 50 |
+
DoNotConvert('tensorflow'),
|
| 51 |
+
DoNotConvert('PIL'),
|
| 52 |
+
DoNotConvert('absl.logging'),
|
| 53 |
+
|
| 54 |
+
# TODO(b/133417201): Remove.
|
| 55 |
+
DoNotConvert('tensorflow_probability'),
|
| 56 |
+
|
| 57 |
+
# TODO(b/133842282): Remove.
|
| 58 |
+
DoNotConvert('tensorflow_datasets.core'),
|
| 59 |
+
|
| 60 |
+
DoNotConvert('keras'),
|
| 61 |
+
DoNotConvert('tf_keras'),
|
| 62 |
+
)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/config_lib.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Global configuration support."""
|
| 16 |
+
|
| 17 |
+
import enum
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
# TODO(mdan): For better performance, allow each rule to take a set names.
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class Rule(object):
|
| 24 |
+
"""Base class for conversion rules."""
|
| 25 |
+
|
| 26 |
+
def __init__(self, module_prefix):
|
| 27 |
+
self._prefix = module_prefix
|
| 28 |
+
|
| 29 |
+
def matches(self, module_name):
|
| 30 |
+
return (module_name.startswith(self._prefix + '.') or
|
| 31 |
+
module_name == self._prefix)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class Action(enum.Enum):
|
| 35 |
+
NONE = 0
|
| 36 |
+
CONVERT = 1
|
| 37 |
+
DO_NOT_CONVERT = 2
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class DoNotConvert(Rule):
|
| 41 |
+
"""Indicates that this module should be not converted."""
|
| 42 |
+
|
| 43 |
+
def __str__(self):
|
| 44 |
+
return 'DoNotConvert rule for {}'.format(self._prefix)
|
| 45 |
+
|
| 46 |
+
def get_action(self, module):
|
| 47 |
+
if self.matches(module.__name__):
|
| 48 |
+
return Action.DO_NOT_CONVERT
|
| 49 |
+
return Action.NONE
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class Convert(Rule):
|
| 53 |
+
"""Indicates that this module should be converted."""
|
| 54 |
+
|
| 55 |
+
def __str__(self):
|
| 56 |
+
return 'Convert rule for {}'.format(self._prefix)
|
| 57 |
+
|
| 58 |
+
def get_action(self, module):
|
| 59 |
+
if self.matches(module.__name__):
|
| 60 |
+
return Action.CONVERT
|
| 61 |
+
return Action.NONE
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter.py
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Converter construction support.
|
| 16 |
+
|
| 17 |
+
This module contains a base class for all converters, as well as supporting
|
| 18 |
+
structures. These structures are referred to as contexts.
|
| 19 |
+
|
| 20 |
+
The class hierarchy is as follows:
|
| 21 |
+
|
| 22 |
+
<your converter>
|
| 23 |
+
[extends] converter.Base
|
| 24 |
+
[extends] transformer.Base
|
| 25 |
+
[extends] gast.nodeTransformer
|
| 26 |
+
[uses] transformer.SourceInfo
|
| 27 |
+
[uses] converter.EntityContext
|
| 28 |
+
[uses] converter.ProgramContext
|
| 29 |
+
[uses] transformer.SourceInfo
|
| 30 |
+
|
| 31 |
+
converter.Base is a specialization of transformer.Base for AutoGraph. It's a
|
| 32 |
+
very lightweight subclass that adds a `ctx` attribute holding the corresponding
|
| 33 |
+
EntityContext object (see below). Note that converters are not reusable, and
|
| 34 |
+
`visit` will raise an error if called more than once.
|
| 35 |
+
|
| 36 |
+
converter.EntityContext contains mutable state associated with an entity that
|
| 37 |
+
the converter processes.
|
| 38 |
+
|
| 39 |
+
converter.ProgramContext contains mutable state across related entities. For
|
| 40 |
+
example, when converting several functions that call one another, the
|
| 41 |
+
ProgramContext should be shared across these entities.
|
| 42 |
+
|
| 43 |
+
Below is the overall flow at conversion:
|
| 44 |
+
|
| 45 |
+
program_ctx = ProgramContext(<entities to convert>, <global settings>, ...)
|
| 46 |
+
while <program_ctx has more entities to convert>:
|
| 47 |
+
entity, source_info = <get next entity from program_ctx>
|
| 48 |
+
entity_ctx = EntityContext(program_ctx, source_info)
|
| 49 |
+
for <each ConverterClass>:
|
| 50 |
+
converter = ConverterClass(entity_ctx)
|
| 51 |
+
|
| 52 |
+
# May update entity_ctx and program_ctx
|
| 53 |
+
entity = converter.visit(entity)
|
| 54 |
+
|
| 55 |
+
<add entity's dependencies to program_ctx>
|
| 56 |
+
|
| 57 |
+
Note that pyct contains a small number of transformers used for static analysis.
|
| 58 |
+
These implement transformer.Base, rather than converter.Base, to avoid a
|
| 59 |
+
dependency on AutoGraph.
|
| 60 |
+
"""
|
| 61 |
+
|
| 62 |
+
import enum
|
| 63 |
+
|
| 64 |
+
from tensorflow.python.autograph.pyct import anno
|
| 65 |
+
from tensorflow.python.autograph.pyct import ast_util
|
| 66 |
+
from tensorflow.python.autograph.pyct import parser
|
| 67 |
+
from tensorflow.python.autograph.pyct import templates
|
| 68 |
+
from tensorflow.python.autograph.pyct import transformer
|
| 69 |
+
from tensorflow.python.util.tf_export import tf_export
|
| 70 |
+
|
| 71 |
+
# TODO(mdan): These contexts can be refactored into first class objects.
|
| 72 |
+
# For example, we could define Program and Entity abstractions that hold on
|
| 73 |
+
# to the actual entity and have conversion methods.
|
| 74 |
+
|
| 75 |
+
# TODO(mdan): Add a test specific to this converter.
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
@tf_export('autograph.experimental.Feature')
|
| 79 |
+
class Feature(enum.Enum):
|
| 80 |
+
"""This enumeration represents optional conversion options.
|
| 81 |
+
|
| 82 |
+
These conversion options are experimental. They are subject to change without
|
| 83 |
+
notice and offer no guarantees.
|
| 84 |
+
|
| 85 |
+
_Example Usage_
|
| 86 |
+
|
| 87 |
+
```python
|
| 88 |
+
optionals= tf.autograph.experimental.Feature.EQUALITY_OPERATORS
|
| 89 |
+
@tf.function(experimental_autograph_options=optionals)
|
| 90 |
+
def f(i):
|
| 91 |
+
if i == 0: # EQUALITY_OPERATORS allows the use of == here.
|
| 92 |
+
tf.print('i is zero')
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
Attributes:
|
| 96 |
+
ALL: Enable all features.
|
| 97 |
+
AUTO_CONTROL_DEPS: Insert of control dependencies in the generated code.
|
| 98 |
+
ASSERT_STATEMENTS: Convert Tensor-dependent assert statements to tf.Assert.
|
| 99 |
+
BUILTIN_FUNCTIONS: Convert builtin functions applied to Tensors to
|
| 100 |
+
their TF counterparts.
|
| 101 |
+
EQUALITY_OPERATORS: Whether to convert the equality operator ('==') to
|
| 102 |
+
tf.math.equal.
|
| 103 |
+
LISTS: Convert list idioms, like initializers, slices, append, etc.
|
| 104 |
+
NAME_SCOPES: Insert name scopes that name ops according to context, like the
|
| 105 |
+
function they were defined in.
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
ALL = 'ALL'
|
| 109 |
+
|
| 110 |
+
AUTO_CONTROL_DEPS = 'AUTO_CONTROL_DEPS'
|
| 111 |
+
ASSERT_STATEMENTS = 'ASSERT_STATEMENTS'
|
| 112 |
+
BUILTIN_FUNCTIONS = 'BUILTIN_FUNCTIONS'
|
| 113 |
+
EQUALITY_OPERATORS = 'EQUALITY_OPERATORS'
|
| 114 |
+
LISTS = 'LISTS'
|
| 115 |
+
NAME_SCOPES = 'NAME_SCOPES'
|
| 116 |
+
|
| 117 |
+
@classmethod
|
| 118 |
+
def all(cls):
|
| 119 |
+
"""Returns a tuple that enables all options."""
|
| 120 |
+
return tuple(cls.__members__.values())
|
| 121 |
+
|
| 122 |
+
@classmethod
|
| 123 |
+
def all_but(cls, exclude):
|
| 124 |
+
"""Returns a tuple that enables all but the excluded options."""
|
| 125 |
+
if not isinstance(exclude, (list, tuple, set)):
|
| 126 |
+
exclude = (exclude,)
|
| 127 |
+
return tuple(set(cls.all()) - set(exclude) - {cls.ALL})
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
STANDARD_OPTIONS = None # Forward definition.
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
class ConversionOptions(object):
|
| 134 |
+
"""Immutable container for global conversion flags.
|
| 135 |
+
|
| 136 |
+
Attributes:
|
| 137 |
+
recursive: bool, whether to recursively convert any user functions or
|
| 138 |
+
classes that the converted function may use.
|
| 139 |
+
user_requested: bool, whether the conversion was explicitly requested by
|
| 140 |
+
the user, as opposed to being performed as a result of other logic. This
|
| 141 |
+
value always auto-resets to False in child conversions.
|
| 142 |
+
optional_features: Union[Feature, Set[Feature]], controls the use of
|
| 143 |
+
optional features in the conversion process. See Feature for available
|
| 144 |
+
options.
|
| 145 |
+
"""
|
| 146 |
+
|
| 147 |
+
def __init__(self,
|
| 148 |
+
recursive=False,
|
| 149 |
+
user_requested=False,
|
| 150 |
+
internal_convert_user_code=True,
|
| 151 |
+
optional_features=Feature.ALL):
|
| 152 |
+
self.recursive = recursive
|
| 153 |
+
self.user_requested = user_requested
|
| 154 |
+
# TODO(mdan): Rename to conversion_recursion_depth?
|
| 155 |
+
self.internal_convert_user_code = internal_convert_user_code
|
| 156 |
+
|
| 157 |
+
if optional_features is None:
|
| 158 |
+
optional_features = ()
|
| 159 |
+
elif isinstance(optional_features, Feature):
|
| 160 |
+
optional_features = (optional_features,)
|
| 161 |
+
optional_features = frozenset(optional_features)
|
| 162 |
+
self.optional_features = optional_features
|
| 163 |
+
|
| 164 |
+
def as_tuple(self):
|
| 165 |
+
return (self.recursive, self.user_requested,
|
| 166 |
+
self.internal_convert_user_code, self.optional_features)
|
| 167 |
+
|
| 168 |
+
def __hash__(self):
|
| 169 |
+
return hash(self.as_tuple())
|
| 170 |
+
|
| 171 |
+
def __eq__(self, other):
|
| 172 |
+
assert isinstance(other, ConversionOptions)
|
| 173 |
+
return self.as_tuple() == other.as_tuple()
|
| 174 |
+
|
| 175 |
+
def __str__(self):
|
| 176 |
+
return 'ConversionOptions[{}]'
|
| 177 |
+
|
| 178 |
+
def uses(self, feature):
|
| 179 |
+
return (Feature.ALL in self.optional_features or
|
| 180 |
+
feature in self.optional_features)
|
| 181 |
+
|
| 182 |
+
def call_options(self):
|
| 183 |
+
"""Returns the corresponding options to be used for recursive conversion."""
|
| 184 |
+
return ConversionOptions(
|
| 185 |
+
recursive=self.recursive,
|
| 186 |
+
user_requested=False,
|
| 187 |
+
internal_convert_user_code=self.recursive,
|
| 188 |
+
optional_features=self.optional_features)
|
| 189 |
+
|
| 190 |
+
def to_ast(self):
|
| 191 |
+
"""Returns a representation of this object as an AST node.
|
| 192 |
+
|
| 193 |
+
The AST node encodes a constructor that would create an object with the
|
| 194 |
+
same contents.
|
| 195 |
+
|
| 196 |
+
Returns:
|
| 197 |
+
ast.Node
|
| 198 |
+
"""
|
| 199 |
+
if self == STANDARD_OPTIONS:
|
| 200 |
+
return parser.parse_expression('ag__.STD')
|
| 201 |
+
|
| 202 |
+
template = """
|
| 203 |
+
ag__.ConversionOptions(
|
| 204 |
+
recursive=recursive_val,
|
| 205 |
+
user_requested=user_requested_val,
|
| 206 |
+
optional_features=optional_features_val,
|
| 207 |
+
internal_convert_user_code=internal_convert_user_code_val)
|
| 208 |
+
"""
|
| 209 |
+
|
| 210 |
+
def list_of_features(values):
|
| 211 |
+
return parser.parse_expression('({})'.format(', '.join(
|
| 212 |
+
'ag__.{}'.format(str(v)) for v in values)))
|
| 213 |
+
|
| 214 |
+
expr_ast = templates.replace(
|
| 215 |
+
template,
|
| 216 |
+
recursive_val=parser.parse_expression(str(self.recursive)),
|
| 217 |
+
user_requested_val=parser.parse_expression(str(self.user_requested)),
|
| 218 |
+
internal_convert_user_code_val=parser.parse_expression(
|
| 219 |
+
str(self.internal_convert_user_code)),
|
| 220 |
+
optional_features_val=list_of_features(self.optional_features))
|
| 221 |
+
return expr_ast[0].value
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
STANDARD_OPTIONS = ConversionOptions(
|
| 225 |
+
recursive=True,
|
| 226 |
+
user_requested=False,
|
| 227 |
+
internal_convert_user_code=True,
|
| 228 |
+
optional_features=None)
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
class ProgramContext(object):
|
| 232 |
+
"""ProgramContext keeps track of converting function hierarchies.
|
| 233 |
+
|
| 234 |
+
Attributes:
|
| 235 |
+
options: ConversionOptions
|
| 236 |
+
autograph_module: Deprecated. Do not use.
|
| 237 |
+
"""
|
| 238 |
+
|
| 239 |
+
def __init__(self, options, autograph_module=None):
|
| 240 |
+
self.options = options
|
| 241 |
+
self.autograph_module = autograph_module
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
class Base(transformer.Base):
|
| 245 |
+
"""All converters should inherit from this class.
|
| 246 |
+
|
| 247 |
+
Attributes:
|
| 248 |
+
ctx: EntityContext
|
| 249 |
+
"""
|
| 250 |
+
|
| 251 |
+
def __init__(self, ctx):
|
| 252 |
+
super(Base, self).__init__(ctx)
|
| 253 |
+
|
| 254 |
+
self._used = False
|
| 255 |
+
self._ast_depth = 0
|
| 256 |
+
|
| 257 |
+
def get_definition_directive(self, node, directive, arg, default):
|
| 258 |
+
"""Returns the unique directive argument for a symbol.
|
| 259 |
+
|
| 260 |
+
See lang/directives.py for details on directives.
|
| 261 |
+
|
| 262 |
+
Example:
|
| 263 |
+
# Given a directive in the code:
|
| 264 |
+
ag.foo_directive(bar, baz=1)
|
| 265 |
+
|
| 266 |
+
# One can write for an AST node Name(id='bar'):
|
| 267 |
+
get_definition_directive(node, ag.foo_directive, 'baz')
|
| 268 |
+
|
| 269 |
+
Args:
|
| 270 |
+
node: ast.AST, the node representing the symbol for which the directive
|
| 271 |
+
argument is needed.
|
| 272 |
+
directive: Callable[..., Any], the directive to search.
|
| 273 |
+
arg: str, the directive argument to return.
|
| 274 |
+
default: Any
|
| 275 |
+
|
| 276 |
+
Raises:
|
| 277 |
+
ValueError: if conflicting annotations have been found
|
| 278 |
+
"""
|
| 279 |
+
defs = anno.getanno(node, anno.Static.ORIG_DEFINITIONS, ())
|
| 280 |
+
if not defs:
|
| 281 |
+
return default
|
| 282 |
+
|
| 283 |
+
arg_values_found = []
|
| 284 |
+
for def_ in defs:
|
| 285 |
+
if (directive in def_.directives and arg in def_.directives[directive]):
|
| 286 |
+
arg_values_found.append(def_.directives[directive][arg])
|
| 287 |
+
|
| 288 |
+
if not arg_values_found:
|
| 289 |
+
return default
|
| 290 |
+
|
| 291 |
+
if len(arg_values_found) == 1:
|
| 292 |
+
return arg_values_found[0]
|
| 293 |
+
|
| 294 |
+
# If multiple annotations reach the symbol, they must all match. If they do,
|
| 295 |
+
# return any of them.
|
| 296 |
+
first_value = arg_values_found[0]
|
| 297 |
+
for other_value in arg_values_found[1:]:
|
| 298 |
+
if not ast_util.matches(first_value, other_value):
|
| 299 |
+
qn = anno.getanno(node, anno.Basic.QN)
|
| 300 |
+
raise ValueError(
|
| 301 |
+
'%s has ambiguous annotations for %s(%s): %s, %s' %
|
| 302 |
+
(qn, directive.__name__, arg, parser.unparse(other_value).strip(),
|
| 303 |
+
parser.unparse(first_value).strip()))
|
| 304 |
+
return first_value
|
| 305 |
+
|
| 306 |
+
def visit(self, node):
|
| 307 |
+
if not self._ast_depth:
|
| 308 |
+
if self._used:
|
| 309 |
+
raise ValueError('converter objects cannot be reused')
|
| 310 |
+
self._used = True
|
| 311 |
+
|
| 312 |
+
self._ast_depth += 1
|
| 313 |
+
try:
|
| 314 |
+
return super(Base, self).visit(node)
|
| 315 |
+
finally:
|
| 316 |
+
self._ast_depth -= 1
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/converter_testing.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Base class for tests in this module."""
|
| 16 |
+
|
| 17 |
+
import contextlib
|
| 18 |
+
import inspect
|
| 19 |
+
import io
|
| 20 |
+
import sys
|
| 21 |
+
import types
|
| 22 |
+
|
| 23 |
+
from tensorflow.python.autograph.core import config
|
| 24 |
+
from tensorflow.python.autograph.core import converter
|
| 25 |
+
from tensorflow.python.autograph.impl import api
|
| 26 |
+
from tensorflow.python.framework import ops
|
| 27 |
+
from tensorflow.python.platform import test
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def allowlist(f):
|
| 31 |
+
"""Helper that marks a callable as whtelitisted."""
|
| 32 |
+
if 'allowlisted_module_for_testing' not in sys.modules:
|
| 33 |
+
allowlisted_mod = types.ModuleType('allowlisted_module_for_testing')
|
| 34 |
+
sys.modules['allowlisted_module_for_testing'] = allowlisted_mod
|
| 35 |
+
config.CONVERSION_RULES = (
|
| 36 |
+
(config.DoNotConvert('allowlisted_module_for_testing'),) +
|
| 37 |
+
config.CONVERSION_RULES)
|
| 38 |
+
|
| 39 |
+
f.__module__ = 'allowlisted_module_for_testing'
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def is_inside_generated_code():
|
| 43 |
+
"""Tests whether the caller is generated code. Implementation-specific."""
|
| 44 |
+
frame = inspect.currentframe()
|
| 45 |
+
try:
|
| 46 |
+
frame = frame.f_back
|
| 47 |
+
|
| 48 |
+
internal_stack_functions = ('converted_call', '_call_unconverted')
|
| 49 |
+
# Walk up the stack until we're out of the internal functions.
|
| 50 |
+
while (frame is not None and
|
| 51 |
+
frame.f_code.co_name in internal_stack_functions):
|
| 52 |
+
frame = frame.f_back
|
| 53 |
+
if frame is None:
|
| 54 |
+
return False
|
| 55 |
+
|
| 56 |
+
return 'ag__' in frame.f_locals
|
| 57 |
+
finally:
|
| 58 |
+
del frame
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class TestingTranspiler(api.PyToTF):
|
| 62 |
+
"""Testing version that only applies given transformations."""
|
| 63 |
+
|
| 64 |
+
def __init__(self, converters, ag_overrides):
|
| 65 |
+
super(TestingTranspiler, self).__init__()
|
| 66 |
+
if isinstance(converters, (list, tuple)):
|
| 67 |
+
self._converters = converters
|
| 68 |
+
else:
|
| 69 |
+
self._converters = (converters,)
|
| 70 |
+
self.transformed_ast = None
|
| 71 |
+
self._ag_overrides = ag_overrides
|
| 72 |
+
|
| 73 |
+
def get_extra_locals(self):
|
| 74 |
+
retval = super(TestingTranspiler, self).get_extra_locals()
|
| 75 |
+
if self._ag_overrides:
|
| 76 |
+
modified_ag = types.ModuleType('fake_autograph')
|
| 77 |
+
modified_ag.__dict__.update(retval['ag__'].__dict__)
|
| 78 |
+
modified_ag.__dict__.update(self._ag_overrides)
|
| 79 |
+
retval['ag__'] = modified_ag
|
| 80 |
+
return retval
|
| 81 |
+
|
| 82 |
+
def transform_ast(self, node, ctx):
|
| 83 |
+
node = self.initial_analysis(node, ctx)
|
| 84 |
+
|
| 85 |
+
for c in self._converters:
|
| 86 |
+
node = c.transform(node, ctx)
|
| 87 |
+
|
| 88 |
+
self.transformed_ast = node
|
| 89 |
+
self.transform_ctx = ctx
|
| 90 |
+
return node
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
class TestCase(test.TestCase):
|
| 94 |
+
"""Base class for unit tests in this module. Contains relevant utilities."""
|
| 95 |
+
|
| 96 |
+
def setUp(self):
|
| 97 |
+
# AutoGraph tests must run in graph mode to properly test control flow.
|
| 98 |
+
self.graph = ops.Graph().as_default()
|
| 99 |
+
self.graph.__enter__()
|
| 100 |
+
|
| 101 |
+
def tearDown(self):
|
| 102 |
+
self.graph.__exit__(None, None, None)
|
| 103 |
+
|
| 104 |
+
@contextlib.contextmanager
|
| 105 |
+
def assertPrints(self, expected_result):
|
| 106 |
+
try:
|
| 107 |
+
out_capturer = io.StringIO()
|
| 108 |
+
sys.stdout = out_capturer
|
| 109 |
+
yield
|
| 110 |
+
self.assertEqual(out_capturer.getvalue(), expected_result)
|
| 111 |
+
finally:
|
| 112 |
+
sys.stdout = sys.__stdout__
|
| 113 |
+
|
| 114 |
+
def transform(
|
| 115 |
+
self, f, converter_module, include_ast=False, ag_overrides=None):
|
| 116 |
+
program_ctx = converter.ProgramContext(
|
| 117 |
+
options=converter.ConversionOptions(recursive=True),
|
| 118 |
+
autograph_module=api)
|
| 119 |
+
|
| 120 |
+
tr = TestingTranspiler(converter_module, ag_overrides)
|
| 121 |
+
transformed, _, _ = tr.transform_function(f, program_ctx)
|
| 122 |
+
|
| 123 |
+
if include_ast:
|
| 124 |
+
return transformed, tr.transformed_ast, tr.transform_ctx
|
| 125 |
+
|
| 126 |
+
return transformed
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/function_wrappers.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Support for wrapping converted functions bodies with auxiliary logic."""
|
| 16 |
+
|
| 17 |
+
from tensorflow.python.autograph.core import ag_ctx
|
| 18 |
+
from tensorflow.python.autograph.core import converter
|
| 19 |
+
from tensorflow.python.autograph.operators import variables
|
| 20 |
+
from tensorflow.python.framework import auto_control_deps
|
| 21 |
+
from tensorflow.python.framework import ops
|
| 22 |
+
from tensorflow.python.framework import tensor_util
|
| 23 |
+
from tensorflow.python.util import nest
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# TODO(mdan): Move this into operators - it represents a function definition.
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class FunctionScope(object):
|
| 30 |
+
"""Context manager that wraps the body of a converted function.
|
| 31 |
+
|
| 32 |
+
This context manager handles various operations related to the scope of a
|
| 33 |
+
function:
|
| 34 |
+
* optional TF name scopes - these name scopes match the name of the
|
| 35 |
+
function, for easy visualization in tensorBoard;
|
| 36 |
+
* optional automatic control dependencies - this adds the same mechanism
|
| 37 |
+
for control dependencies that is used by `@tf.function`; it can be
|
| 38 |
+
optionally enabled when using `tf.autograph.to_graph`;
|
| 39 |
+
* tracking of autograph conversion state (whether it's enabled by the user,
|
| 40 |
+
conversion options;
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
def __init__(self, function_name, scope_name, options):
|
| 44 |
+
self.name = scope_name
|
| 45 |
+
self.options = options
|
| 46 |
+
|
| 47 |
+
if options.user_requested:
|
| 48 |
+
self.autograph_ctx = ag_ctx.ControlStatusCtx(ag_ctx.Status.ENABLED,
|
| 49 |
+
options)
|
| 50 |
+
self.callopts = options.call_options()
|
| 51 |
+
|
| 52 |
+
use_name_scope = options.uses(converter.Feature.NAME_SCOPES)
|
| 53 |
+
self.use_name_scope = use_name_scope
|
| 54 |
+
if use_name_scope:
|
| 55 |
+
self.name_scope = ops.name_scope(self._sanitize(function_name))
|
| 56 |
+
|
| 57 |
+
use_auto_deps = self.options.uses(converter.Feature.AUTO_CONTROL_DEPS)
|
| 58 |
+
self.use_auto_deps = use_auto_deps
|
| 59 |
+
if use_auto_deps:
|
| 60 |
+
self.autodeps_scope = auto_control_deps.AutomaticControlDependencies()
|
| 61 |
+
self._return_value_marked = False
|
| 62 |
+
|
| 63 |
+
def _sanitize(self, name):
|
| 64 |
+
"""See https://www.tensorflow.org/api_docs/python/tf/Graph#name_scope."""
|
| 65 |
+
# TensorFlow doesn't like leading underscores at the top level.
|
| 66 |
+
if name and name.startswith('_'):
|
| 67 |
+
name = 'fn' + name
|
| 68 |
+
return name
|
| 69 |
+
|
| 70 |
+
def __enter__(self):
|
| 71 |
+
if self.options.user_requested:
|
| 72 |
+
self.autograph_ctx.__enter__()
|
| 73 |
+
if self.use_name_scope:
|
| 74 |
+
self.name_scope.__enter__()
|
| 75 |
+
if self.use_auto_deps:
|
| 76 |
+
self.autodeps_scope.__enter__()
|
| 77 |
+
return self
|
| 78 |
+
|
| 79 |
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
| 80 |
+
if self.options.user_requested:
|
| 81 |
+
self.autograph_ctx.__exit__(exc_type, exc_val, exc_tb)
|
| 82 |
+
if self.use_name_scope:
|
| 83 |
+
self.name_scope.__exit__(exc_type, exc_val, exc_tb)
|
| 84 |
+
if self.use_auto_deps:
|
| 85 |
+
self.autodeps_scope.__exit__(exc_type, exc_val, exc_tb)
|
| 86 |
+
|
| 87 |
+
def ret(self, value, did_return):
|
| 88 |
+
"""Marks a value as returned from the function guarded by the scope."""
|
| 89 |
+
del did_return
|
| 90 |
+
|
| 91 |
+
if isinstance(value, variables.UndefinedReturnValue):
|
| 92 |
+
return None
|
| 93 |
+
|
| 94 |
+
if self.use_auto_deps:
|
| 95 |
+
self._return_value_marked = True
|
| 96 |
+
if value is None:
|
| 97 |
+
# We don't create dummy returns, to preserve Python semantics. The user
|
| 98 |
+
# is responsible for adding a return value to the top-level function.
|
| 99 |
+
return None
|
| 100 |
+
|
| 101 |
+
def _mark_return_if_tensor(t):
|
| 102 |
+
if tensor_util.is_tf_type(t):
|
| 103 |
+
return self.autodeps_scope.mark_as_return(t)
|
| 104 |
+
return t
|
| 105 |
+
|
| 106 |
+
value = nest.map_structure(_mark_return_if_tensor, value)
|
| 107 |
+
return value
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def with_function_scope(thunk, scope_name, options):
|
| 111 |
+
"""Inline version of the FunctionScope context manager."""
|
| 112 |
+
with FunctionScope('lambda_', scope_name, options) as scope:
|
| 113 |
+
return thunk(scope)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/core/unsupported_features_checker.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Checkers for detecting unsupported Python features."""
|
| 16 |
+
|
| 17 |
+
import gast
|
| 18 |
+
|
| 19 |
+
from tensorflow.python.autograph.pyct import errors
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class UnsupportedFeaturesChecker(gast.NodeVisitor):
|
| 23 |
+
"""Quick check for Python features we know we don't support.
|
| 24 |
+
|
| 25 |
+
Any features detected will cause AutoGraph to not compile a function.
|
| 26 |
+
"""
|
| 27 |
+
|
| 28 |
+
def visit_Attribute(self, node):
|
| 29 |
+
if (node.attr is not None
|
| 30 |
+
and node.attr.startswith('__') and not node.attr.endswith('__')):
|
| 31 |
+
raise errors.UnsupportedLanguageElementError(
|
| 32 |
+
'mangled names are not yet supported')
|
| 33 |
+
self.generic_visit(node)
|
| 34 |
+
|
| 35 |
+
def visit_For(self, node):
|
| 36 |
+
if node.orelse:
|
| 37 |
+
raise errors.UnsupportedLanguageElementError(
|
| 38 |
+
'for/else statement not yet supported')
|
| 39 |
+
self.generic_visit(node)
|
| 40 |
+
|
| 41 |
+
def visit_While(self, node):
|
| 42 |
+
if node.orelse:
|
| 43 |
+
raise errors.UnsupportedLanguageElementError(
|
| 44 |
+
'while/else statement not yet supported')
|
| 45 |
+
self.generic_visit(node)
|
| 46 |
+
|
| 47 |
+
# These checks could potentially be replaced with inspect.isgeneratorfunction
|
| 48 |
+
# to avoid a getsource/parse/ast-walk round trip.
|
| 49 |
+
def visit_Yield(self, node):
|
| 50 |
+
raise errors.UnsupportedLanguageElementError('generators are not supported')
|
| 51 |
+
|
| 52 |
+
def visit_YieldFrom(self, node):
|
| 53 |
+
raise errors.UnsupportedLanguageElementError('generators are not supported')
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def verify(node):
|
| 57 |
+
UnsupportedFeaturesChecker().visit(node)
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__init__.py
ADDED
|
File without changes
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (208 Bytes). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/api.cpython-310.pyc
ADDED
|
Binary file (26.5 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/__pycache__/conversion.cpython-310.pyc
ADDED
|
Binary file (5.19 kB). View file
|
|
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/api.py
ADDED
|
@@ -0,0 +1,949 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""This module contains the user- and codegen-facing API for AutoGraph."""
|
| 16 |
+
|
| 17 |
+
import functools
|
| 18 |
+
import importlib
|
| 19 |
+
import inspect
|
| 20 |
+
import os
|
| 21 |
+
import sys
|
| 22 |
+
import textwrap
|
| 23 |
+
import traceback
|
| 24 |
+
|
| 25 |
+
from tensorflow.python.autograph import operators
|
| 26 |
+
from tensorflow.python.autograph import utils
|
| 27 |
+
from tensorflow.python.autograph.converters import asserts
|
| 28 |
+
from tensorflow.python.autograph.converters import break_statements
|
| 29 |
+
from tensorflow.python.autograph.converters import call_trees
|
| 30 |
+
from tensorflow.python.autograph.converters import conditional_expressions
|
| 31 |
+
from tensorflow.python.autograph.converters import continue_statements
|
| 32 |
+
from tensorflow.python.autograph.converters import control_flow
|
| 33 |
+
from tensorflow.python.autograph.converters import directives
|
| 34 |
+
from tensorflow.python.autograph.converters import functions
|
| 35 |
+
from tensorflow.python.autograph.converters import lists
|
| 36 |
+
from tensorflow.python.autograph.converters import logical_expressions
|
| 37 |
+
from tensorflow.python.autograph.converters import return_statements
|
| 38 |
+
from tensorflow.python.autograph.converters import slices
|
| 39 |
+
from tensorflow.python.autograph.converters import variables
|
| 40 |
+
from tensorflow.python.autograph.core import ag_ctx
|
| 41 |
+
from tensorflow.python.autograph.core import converter
|
| 42 |
+
from tensorflow.python.autograph.core import function_wrappers
|
| 43 |
+
from tensorflow.python.autograph.core import unsupported_features_checker
|
| 44 |
+
from tensorflow.python.autograph.impl import conversion
|
| 45 |
+
from tensorflow.python.autograph.lang import special_functions
|
| 46 |
+
from tensorflow.python.autograph.operators import py_builtins
|
| 47 |
+
from tensorflow.python.autograph.pyct import anno
|
| 48 |
+
from tensorflow.python.autograph.pyct import cfg
|
| 49 |
+
from tensorflow.python.autograph.pyct import error_utils
|
| 50 |
+
from tensorflow.python.autograph.pyct import errors
|
| 51 |
+
from tensorflow.python.autograph.pyct import inspect_utils
|
| 52 |
+
from tensorflow.python.autograph.pyct import origin_info
|
| 53 |
+
from tensorflow.python.autograph.pyct import qual_names
|
| 54 |
+
from tensorflow.python.autograph.pyct import transpiler
|
| 55 |
+
from tensorflow.python.autograph.pyct.static_analysis import activity
|
| 56 |
+
from tensorflow.python.autograph.pyct.static_analysis import reaching_definitions
|
| 57 |
+
from tensorflow.python.autograph.utils import ag_logging as logging
|
| 58 |
+
from tensorflow.python.eager.polymorphic_function import tf_method_target
|
| 59 |
+
from tensorflow.python.framework import errors_impl
|
| 60 |
+
from tensorflow.python.util import tf_decorator
|
| 61 |
+
from tensorflow.python.util import tf_inspect
|
| 62 |
+
from tensorflow.python.util import tf_stack
|
| 63 |
+
from tensorflow.python.util.tf_export import tf_export
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def is_autograph_strict_conversion_mode():
|
| 67 |
+
return int(os.environ.get('AUTOGRAPH_STRICT_CONVERSION', '0')) > 0
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
#
|
| 71 |
+
# Error handling
|
| 72 |
+
#
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# TODO(mdan): Export this symbol.
|
| 76 |
+
class AutoGraphError(errors.PyCTError):
|
| 77 |
+
"""Base class for all AutoGraph exceptions."""
|
| 78 |
+
pass
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
class ConversionError(AutoGraphError):
|
| 82 |
+
"""Raised during the conversion process."""
|
| 83 |
+
pass
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
class StagingError(AutoGraphError):
|
| 87 |
+
"""Raised during the staging (i.e. Python execution) of converted code."""
|
| 88 |
+
pass
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
class _ErrorMetadata(error_utils.ErrorMetadataBase):
|
| 92 |
+
"""AutoGraph-specific error metadata. See base class."""
|
| 93 |
+
|
| 94 |
+
def create_exception(self, source_error):
|
| 95 |
+
preferred_type = type(source_error)
|
| 96 |
+
if issubclass(preferred_type, errors_impl.OpError):
|
| 97 |
+
# Best-effort unpacking of OpError exceptions.
|
| 98 |
+
# TODO(mdan): Use a mechanism that is more future-proof.
|
| 99 |
+
init_argspec = tf_inspect.getfullargspec(preferred_type.__init__)
|
| 100 |
+
message = self.get_message()
|
| 101 |
+
init_args = tuple(init_argspec.args)
|
| 102 |
+
# At the time of this writing, TF errors either take 3 or 4 arguments,
|
| 103 |
+
# the argument '*args' may or may not be used.
|
| 104 |
+
if init_args == ('self', 'node_def', 'op', 'message'):
|
| 105 |
+
return preferred_type(source_error.node_def, source_error.op, message,
|
| 106 |
+
source_error.experimental_payloads)
|
| 107 |
+
|
| 108 |
+
elif preferred_type in (errors.PyCTError, AutoGraphError, ConversionError,
|
| 109 |
+
StagingError, errors_impl.InaccessibleTensorError,
|
| 110 |
+
errors_impl.OperatorNotAllowedInGraphError):
|
| 111 |
+
return preferred_type(self.get_message())
|
| 112 |
+
|
| 113 |
+
exc = super(_ErrorMetadata, self).create_exception(source_error)
|
| 114 |
+
if exc is not None:
|
| 115 |
+
return exc
|
| 116 |
+
|
| 117 |
+
# Note: While changing an error's message property to change the message it
|
| 118 |
+
# displays will probably work a lot of times, there is no standard way in
|
| 119 |
+
# Python to do that. The safest way is therefore to create a new exception.
|
| 120 |
+
# For user defined exceptions, we could define an interface that allowed
|
| 121 |
+
# them to work under this mechanism.
|
| 122 |
+
return StagingError(self.get_message())
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def _attach_error_metadata(e, f):
|
| 126 |
+
"""Augments an error with the metadata necessary for rewrite."""
|
| 127 |
+
if hasattr(e, 'ag_pass_through'):
|
| 128 |
+
return
|
| 129 |
+
|
| 130 |
+
metadata = getattr(e, 'ag_error_metadata', None)
|
| 131 |
+
source_map = f.ag_source_map
|
| 132 |
+
|
| 133 |
+
if metadata is None:
|
| 134 |
+
logging.log(1, 'Caught error in user callable %s', f, exc_info=True)
|
| 135 |
+
message = '{}: {}'.format(e.__class__.__name__, e)
|
| 136 |
+
else:
|
| 137 |
+
message = None
|
| 138 |
+
|
| 139 |
+
cause_tb = traceback.extract_tb(sys.exc_info()[2])[1:]
|
| 140 |
+
|
| 141 |
+
e.ag_error_metadata = _ErrorMetadata(cause_tb, metadata, message, source_map,
|
| 142 |
+
__file__)
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
class StackTraceMapper(tf_stack.StackTraceMapper):
|
| 146 |
+
"""Remaps generated code to code it originated from."""
|
| 147 |
+
|
| 148 |
+
def __init__(self, converted_fn):
|
| 149 |
+
super().__init__()
|
| 150 |
+
self._source_map = converted_fn.ag_source_map
|
| 151 |
+
# This may be called repeatedly: once on entry, by the superclass, then by
|
| 152 |
+
# each child context manager.
|
| 153 |
+
self._cached_map = None
|
| 154 |
+
|
| 155 |
+
def get_effective_source_map(self):
|
| 156 |
+
if self._cached_map is not None:
|
| 157 |
+
return self._cached_map
|
| 158 |
+
|
| 159 |
+
parent_map = self.parent.get_effective_source_map()
|
| 160 |
+
|
| 161 |
+
effective_source_map = {}
|
| 162 |
+
for loc, origin in self._source_map.items():
|
| 163 |
+
effective_source_map[(loc.filename, loc.lineno)] = (origin.loc.filename,
|
| 164 |
+
origin.loc.lineno,
|
| 165 |
+
origin.function_name)
|
| 166 |
+
|
| 167 |
+
for key, value in parent_map.items():
|
| 168 |
+
filename, lineno, _ = value
|
| 169 |
+
value_loc = origin_info.LineLocation(filename=filename, lineno=lineno)
|
| 170 |
+
if value_loc in self._source_map:
|
| 171 |
+
origin = self._source_map[value_loc]
|
| 172 |
+
effective_source_map[key] = (origin.loc.filename, origin.loc.lineno,
|
| 173 |
+
origin.function_name)
|
| 174 |
+
else:
|
| 175 |
+
effective_source_map[key] = value
|
| 176 |
+
|
| 177 |
+
self._cached_map = effective_source_map
|
| 178 |
+
return effective_source_map
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
#
|
| 182 |
+
# Actual source code transformation
|
| 183 |
+
#
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
class PyToTF(transpiler.PyToPy):
|
| 187 |
+
"""The TensorFlow AutoGraph transformer."""
|
| 188 |
+
|
| 189 |
+
def __init__(self):
|
| 190 |
+
super(PyToTF, self).__init__()
|
| 191 |
+
self._extra_locals = None
|
| 192 |
+
|
| 193 |
+
def get_transformed_name(self, node):
|
| 194 |
+
return 'tf__' + super(PyToTF, self).get_transformed_name(node)
|
| 195 |
+
|
| 196 |
+
def get_extra_locals(self):
|
| 197 |
+
if self._extra_locals is None:
|
| 198 |
+
# TODO(mdan): Move into core or replace with an actual importable module.
|
| 199 |
+
# Craft a module that exposes the external API as well as certain
|
| 200 |
+
# internal modules.
|
| 201 |
+
module_spec = importlib.machinery.ModuleSpec('autograph', None)
|
| 202 |
+
ag_internal = importlib.util.module_from_spec(module_spec)
|
| 203 |
+
ag_internal.__dict__.update(inspect.getmodule(PyToTF).__dict__)
|
| 204 |
+
ag_internal.ConversionOptions = converter.ConversionOptions
|
| 205 |
+
ag_internal.STD = converter.STANDARD_OPTIONS
|
| 206 |
+
ag_internal.Feature = converter.Feature
|
| 207 |
+
ag_internal.utils = utils
|
| 208 |
+
ag_internal.FunctionScope = function_wrappers.FunctionScope
|
| 209 |
+
ag_internal.with_function_scope = function_wrappers.with_function_scope
|
| 210 |
+
# TODO(mdan): Add safeguards against name clashes.
|
| 211 |
+
# We don't want to create a submodule because we want the operators to be
|
| 212 |
+
# accessible as ag__.<operator>
|
| 213 |
+
ag_internal.__dict__.update(special_functions.__dict__)
|
| 214 |
+
ag_internal.__dict__.update(operators.__dict__)
|
| 215 |
+
|
| 216 |
+
self._extra_locals = {'ag__': ag_internal}
|
| 217 |
+
return self._extra_locals
|
| 218 |
+
|
| 219 |
+
def get_caching_key(self, ctx):
|
| 220 |
+
return ctx.options
|
| 221 |
+
|
| 222 |
+
def initial_analysis(self, node, ctx):
|
| 223 |
+
graphs = cfg.build(node)
|
| 224 |
+
node = qual_names.resolve(node)
|
| 225 |
+
node = activity.resolve(node, ctx, None)
|
| 226 |
+
node = reaching_definitions.resolve(node, ctx, graphs)
|
| 227 |
+
anno.dup(
|
| 228 |
+
node,
|
| 229 |
+
{
|
| 230 |
+
anno.Static.DEFINITIONS: anno.Static.ORIG_DEFINITIONS,
|
| 231 |
+
},
|
| 232 |
+
)
|
| 233 |
+
return node
|
| 234 |
+
|
| 235 |
+
def transform_ast(self, node, ctx):
|
| 236 |
+
unsupported_features_checker.verify(node)
|
| 237 |
+
node = self.initial_analysis(node, ctx)
|
| 238 |
+
|
| 239 |
+
node = functions.transform(node, ctx)
|
| 240 |
+
node = directives.transform(node, ctx)
|
| 241 |
+
node = break_statements.transform(node, ctx)
|
| 242 |
+
if ctx.user.options.uses(converter.Feature.ASSERT_STATEMENTS):
|
| 243 |
+
node = asserts.transform(node, ctx)
|
| 244 |
+
# Note: sequencing continue canonicalization before for loop one avoids
|
| 245 |
+
# dealing with the extra loop increment operation that the for
|
| 246 |
+
# canonicalization creates.
|
| 247 |
+
node = continue_statements.transform(node, ctx)
|
| 248 |
+
node = return_statements.transform(node, ctx)
|
| 249 |
+
if ctx.user.options.uses(converter.Feature.LISTS):
|
| 250 |
+
node = lists.transform(node, ctx)
|
| 251 |
+
node = slices.transform(node, ctx)
|
| 252 |
+
node = call_trees.transform(node, ctx)
|
| 253 |
+
node = control_flow.transform(node, ctx)
|
| 254 |
+
node = conditional_expressions.transform(node, ctx)
|
| 255 |
+
node = logical_expressions.transform(node, ctx)
|
| 256 |
+
node = variables.transform(node, ctx)
|
| 257 |
+
return node
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def _convert_actual(entity, program_ctx):
|
| 261 |
+
"""Applies AutoGraph to entity."""
|
| 262 |
+
|
| 263 |
+
# TODO(mdan): Put these extra fields inside __autograph_info__.
|
| 264 |
+
if not hasattr(entity, '__code__'):
|
| 265 |
+
raise ValueError('Cannot apply autograph to a function that doesn\'t '
|
| 266 |
+
'expose a __code__ object. If this is a @tf.function,'
|
| 267 |
+
' try passing f.python_function instead.')
|
| 268 |
+
|
| 269 |
+
transformed, module, source_map = _TRANSPILER.transform(entity, program_ctx)
|
| 270 |
+
|
| 271 |
+
assert not hasattr(transformed, 'ag_module')
|
| 272 |
+
assert not hasattr(transformed, 'ag_source_map')
|
| 273 |
+
transformed.ag_module = module
|
| 274 |
+
transformed.ag_source_map = source_map
|
| 275 |
+
return transformed
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
#
|
| 279 |
+
# Generated code support
|
| 280 |
+
#
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
def autograph_artifact(entity, extras=None):
|
| 284 |
+
if inspect.ismethod(entity):
|
| 285 |
+
setattr(entity.__func__, 'autograph_info__', extras)
|
| 286 |
+
else:
|
| 287 |
+
setattr(entity, 'autograph_info__', extras)
|
| 288 |
+
return entity
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def is_autograph_artifact(entity):
|
| 292 |
+
return hasattr(entity, 'autograph_info__')
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
def converted_call(f, args, kwargs, caller_fn_scope=None, options=None):
|
| 296 |
+
"""Converts a function call inline.
|
| 297 |
+
|
| 298 |
+
For internal use only.
|
| 299 |
+
|
| 300 |
+
Note: The argument list is optimized for readability of generated code, which
|
| 301 |
+
may look like this:
|
| 302 |
+
|
| 303 |
+
ag__.converted_call(f, (arg1, arg2), None, fscope)
|
| 304 |
+
ag__.converted_call(f, (), dict(arg1=val1, **kwargs), fscope)
|
| 305 |
+
ag__.converted_call(f, (arg1, arg2) + varargs, dict(**kwargs), lscope)
|
| 306 |
+
|
| 307 |
+
Args:
|
| 308 |
+
f: The function to convert.
|
| 309 |
+
args: Tuple, the original positional arguments of f
|
| 310 |
+
kwargs: Optional[Dict], the original keyword arguments of f
|
| 311 |
+
caller_fn_scope: Optional[function_wrappers.FunctionScope], the function
|
| 312 |
+
scope of the converted function in which this call was originally made.
|
| 313 |
+
options: Optional[converter.ConversionOptions], conversion options. If not
|
| 314 |
+
specified, the value of caller_fn_scope.callopts is used. Either options
|
| 315 |
+
or caller_fn_scope must be present.
|
| 316 |
+
|
| 317 |
+
Returns:
|
| 318 |
+
Any, the result of executing a possibly-converted `f` with the given
|
| 319 |
+
arguments.
|
| 320 |
+
"""
|
| 321 |
+
logging.log(1, 'Converted call: %s\n args: %s\n kwargs: %s\n', f, args,
|
| 322 |
+
kwargs)
|
| 323 |
+
|
| 324 |
+
if options is None:
|
| 325 |
+
if caller_fn_scope is None:
|
| 326 |
+
raise ValueError('either caller_fn_scope or options must have a value')
|
| 327 |
+
options = caller_fn_scope.callopts
|
| 328 |
+
|
| 329 |
+
if conversion.is_in_allowlist_cache(f, options):
|
| 330 |
+
logging.log(2, 'Allowlisted %s: from cache', f)
|
| 331 |
+
return _call_unconverted(f, args, kwargs, options, False)
|
| 332 |
+
|
| 333 |
+
if ag_ctx.control_status_ctx().status == ag_ctx.Status.DISABLED:
|
| 334 |
+
logging.log(2, 'Allowlisted: %s: AutoGraph is disabled in context', f)
|
| 335 |
+
return _call_unconverted(f, args, kwargs, options, False)
|
| 336 |
+
|
| 337 |
+
if is_autograph_artifact(f):
|
| 338 |
+
logging.log(2, 'Permanently allowed: %s: AutoGraph artifact', f)
|
| 339 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 340 |
+
|
| 341 |
+
# If this is a partial, unwrap it and redo all the checks.
|
| 342 |
+
if isinstance(f, functools.partial):
|
| 343 |
+
new_kwargs = {}
|
| 344 |
+
if f.keywords is not None:
|
| 345 |
+
# Use copy to avoid mutating the underlying keywords.
|
| 346 |
+
new_kwargs = f.keywords.copy()
|
| 347 |
+
if kwargs is not None:
|
| 348 |
+
new_kwargs.update(kwargs)
|
| 349 |
+
new_args = f.args + args
|
| 350 |
+
logging.log(3, 'Forwarding call of partial %s with\n%s\n%s\n', f, new_args,
|
| 351 |
+
new_kwargs)
|
| 352 |
+
return converted_call(
|
| 353 |
+
f.func,
|
| 354 |
+
new_args,
|
| 355 |
+
new_kwargs,
|
| 356 |
+
caller_fn_scope=caller_fn_scope,
|
| 357 |
+
options=options)
|
| 358 |
+
|
| 359 |
+
if inspect_utils.isbuiltin(f):
|
| 360 |
+
if f is eval:
|
| 361 |
+
return py_builtins.eval_in_original_context(f, args, caller_fn_scope)
|
| 362 |
+
if f is super:
|
| 363 |
+
return py_builtins.super_in_original_context(f, args, caller_fn_scope)
|
| 364 |
+
if f is globals:
|
| 365 |
+
return py_builtins.globals_in_original_context(caller_fn_scope)
|
| 366 |
+
if f is locals:
|
| 367 |
+
return py_builtins.locals_in_original_context(caller_fn_scope)
|
| 368 |
+
if kwargs:
|
| 369 |
+
return py_builtins.overload_of(f)(*args, **kwargs)
|
| 370 |
+
else:
|
| 371 |
+
return py_builtins.overload_of(f)(*args)
|
| 372 |
+
|
| 373 |
+
if conversion.is_unsupported(f):
|
| 374 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 375 |
+
|
| 376 |
+
if not options.user_requested and conversion.is_allowlisted(f):
|
| 377 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 378 |
+
|
| 379 |
+
# internal_convert_user_code is for example turned off when issuing a dynamic
|
| 380 |
+
# call conversion from generated code while in nonrecursive mode. In that
|
| 381 |
+
# case we evidently don't want to recurse, but we still have to convert
|
| 382 |
+
# things like builtins.
|
| 383 |
+
if not options.internal_convert_user_code:
|
| 384 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 385 |
+
|
| 386 |
+
try:
|
| 387 |
+
if inspect.ismethod(f) or inspect.isfunction(f):
|
| 388 |
+
target_entity = f
|
| 389 |
+
effective_args = args
|
| 390 |
+
|
| 391 |
+
f_self = getattr(f, '__self__', None)
|
| 392 |
+
if f_self is not None:
|
| 393 |
+
if isinstance(f_self, tf_method_target.TfMethodTarget):
|
| 394 |
+
f_self = f_self.target
|
| 395 |
+
effective_args = (f_self,) + effective_args
|
| 396 |
+
|
| 397 |
+
elif hasattr(f, '__class__') and hasattr(f.__class__, '__call__'):
|
| 398 |
+
# Callable objects. Dunder methods have special lookup rules, see:
|
| 399 |
+
# https://docs.python.org/3/reference/datamodel.html#specialnames
|
| 400 |
+
# TODO(mdan): Recurse into converted_call to simplify other verifications.
|
| 401 |
+
# This should be handled in the same way as partials.
|
| 402 |
+
target_entity = f.__class__.__call__
|
| 403 |
+
effective_args = (f,) + args
|
| 404 |
+
|
| 405 |
+
else:
|
| 406 |
+
target_entity = f
|
| 407 |
+
raise NotImplementedError('unknown callable type "%s"' % type(f))
|
| 408 |
+
|
| 409 |
+
except Exception as e: # pylint:disable=broad-except
|
| 410 |
+
logging.log(1, 'Error transforming entity %s', target_entity, exc_info=True)
|
| 411 |
+
if is_autograph_strict_conversion_mode():
|
| 412 |
+
raise
|
| 413 |
+
return _fall_back_unconverted(f, args, kwargs, options, e)
|
| 414 |
+
|
| 415 |
+
if not hasattr(target_entity, '__code__'):
|
| 416 |
+
logging.log(2, 'Permanently allowed: %s: native binding', target_entity)
|
| 417 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 418 |
+
elif (hasattr(target_entity.__code__, 'co_filename') and
|
| 419 |
+
target_entity.__code__.co_filename == '<string>'):
|
| 420 |
+
# TODO(mdan): __globals__['txt'] might work in Py3.
|
| 421 |
+
logging.log(2, 'Permanently allowed: %s: dynamic code (exec?)',
|
| 422 |
+
target_entity)
|
| 423 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 424 |
+
|
| 425 |
+
try:
|
| 426 |
+
program_ctx = converter.ProgramContext(options=options)
|
| 427 |
+
converted_f = _convert_actual(target_entity, program_ctx)
|
| 428 |
+
if logging.has_verbosity(2):
|
| 429 |
+
_log_callargs(converted_f, effective_args, kwargs)
|
| 430 |
+
except Exception as e: # pylint:disable=broad-except
|
| 431 |
+
logging.log(1, 'Error transforming entity %s', target_entity, exc_info=True)
|
| 432 |
+
if is_autograph_strict_conversion_mode():
|
| 433 |
+
raise
|
| 434 |
+
return _fall_back_unconverted(f, args, kwargs, options, e)
|
| 435 |
+
|
| 436 |
+
with StackTraceMapper(converted_f), tf_stack.CurrentModuleFilter():
|
| 437 |
+
try:
|
| 438 |
+
if kwargs is not None:
|
| 439 |
+
result = converted_f(*effective_args, **kwargs)
|
| 440 |
+
else:
|
| 441 |
+
result = converted_f(*effective_args)
|
| 442 |
+
except Exception as e:
|
| 443 |
+
_attach_error_metadata(e, converted_f)
|
| 444 |
+
raise
|
| 445 |
+
|
| 446 |
+
return result
|
| 447 |
+
|
| 448 |
+
|
| 449 |
+
def _call_unconverted(f, args, kwargs, options, update_cache=True):
|
| 450 |
+
"""Calls the original function without converting with AutoGraph."""
|
| 451 |
+
if update_cache:
|
| 452 |
+
conversion.cache_allowlisted(f, options)
|
| 453 |
+
|
| 454 |
+
if (inspect.ismethod(f) and
|
| 455 |
+
isinstance(f.__self__, tf_method_target.TfMethodTarget)):
|
| 456 |
+
return f.__self__.call(args, kwargs)
|
| 457 |
+
|
| 458 |
+
if kwargs is not None:
|
| 459 |
+
return f(*args, **kwargs)
|
| 460 |
+
return f(*args)
|
| 461 |
+
|
| 462 |
+
|
| 463 |
+
def _fall_back_unconverted(f, args, kwargs, options, exc):
|
| 464 |
+
"""Falls back to calling the function unconverted, in case of error."""
|
| 465 |
+
# TODO(mdan): Consider adding an internal metric.
|
| 466 |
+
warning_template = (
|
| 467 |
+
'AutoGraph could not transform %s and will run it as-is.\n'
|
| 468 |
+
'%s'
|
| 469 |
+
'Cause: %s\n'
|
| 470 |
+
'To silence this warning, decorate the function with'
|
| 471 |
+
' @tf.autograph.experimental.do_not_convert')
|
| 472 |
+
if isinstance(exc, errors.InaccessibleSourceCodeError):
|
| 473 |
+
if ag_ctx.INSPECT_SOURCE_SUPPORTED:
|
| 474 |
+
logging.warning(warning_template, f, '', exc)
|
| 475 |
+
elif isinstance(exc, errors.UnsupportedLanguageElementError):
|
| 476 |
+
if not conversion.is_in_allowlist_cache(f, options):
|
| 477 |
+
logging.warning(warning_template, f, '', exc)
|
| 478 |
+
else:
|
| 479 |
+
file_bug_message = (
|
| 480 |
+
'Please report this to the TensorFlow team. When filing the bug, set'
|
| 481 |
+
' the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and'
|
| 482 |
+
' attach the full output.\n')
|
| 483 |
+
logging.warning(warning_template, f, file_bug_message, exc)
|
| 484 |
+
|
| 485 |
+
return _call_unconverted(f, args, kwargs, options)
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
#
|
| 489 |
+
# TensorFlow integration
|
| 490 |
+
#
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
@tf_export('__internal__.autograph.tf_convert', v1=[])
|
| 494 |
+
def tf_convert(f, ctx, convert_by_default=True, user_requested=False):
|
| 495 |
+
"""Decorator that applies AutoGraph to a function.
|
| 496 |
+
|
| 497 |
+
Use in internal APIs.
|
| 498 |
+
|
| 499 |
+
This API is suitable for high order functions internal to the TensorFlow API,
|
| 500 |
+
and more generally any function to which AutoGraph is not applied.
|
| 501 |
+
|
| 502 |
+
Guidance: `convert` was a decorator meant for use directly by developers, but
|
| 503 |
+
most of today's uses go through `tf.function`. `tf_convert` is to be called
|
| 504 |
+
from high order functions internal to TF. By default, all the internal
|
| 505 |
+
TensorFlow functions are skipped when AutoGraph processes the code. This may
|
| 506 |
+
lead to user-supplied functions to be incorrectly skipped as well.
|
| 507 |
+
`tf_convert` helps avoid that. See the following example for more details.
|
| 508 |
+
|
| 509 |
+
```
|
| 510 |
+
=====tf_internal_module.py=====
|
| 511 |
+
|
| 512 |
+
def unconverted(input_fn):
|
| 513 |
+
return input_fn()
|
| 514 |
+
|
| 515 |
+
def converted(input_fn):
|
| 516 |
+
return tf.__internal__.autograph.tf_convert(
|
| 517 |
+
input_fn, ctx=tf.__internal__.autograph.control_status_ctx())()
|
| 518 |
+
|
| 519 |
+
======user_module.py======
|
| 520 |
+
|
| 521 |
+
@tf.function
|
| 522 |
+
def foo(input_fn)
|
| 523 |
+
return unconverted(input_fn)
|
| 524 |
+
|
| 525 |
+
@tf.function
|
| 526 |
+
def bar(input_fn)
|
| 527 |
+
return converted(input_fn)
|
| 528 |
+
|
| 529 |
+
@tf.function(autograph=False)
|
| 530 |
+
def baz(input_fn)
|
| 531 |
+
return converted(input_fn)
|
| 532 |
+
```
|
| 533 |
+
|
| 534 |
+
The `foo` method above will execute the `input_fn` without autograph
|
| 535 |
+
conversion, while the `bar` method will run an autographed `input_fn`. The
|
| 536 |
+
`baz` method will run an unconverted `input_fn`, since `tf_convert` respect
|
| 537 |
+
the control status context.
|
| 538 |
+
|
| 539 |
+
Note that both methods in `tf_internal_module` are skipped by autograph when
|
| 540 |
+
tracing the `tf.function`. The configuration of whether a module/package
|
| 541 |
+
should be skipped by autograph is controlled in
|
| 542 |
+
tensorflow/python/autograph/core/config.py.
|
| 543 |
+
|
| 544 |
+
Args:
|
| 545 |
+
f: Callable.
|
| 546 |
+
ctx: ag_ctx.ControlStatusCtx, the Autograph context in which `f` is used.
|
| 547 |
+
convert_by_default: bool, whether to use AutoGraph when the context doesn't
|
| 548 |
+
specify.
|
| 549 |
+
user_requested: bool, whether to ignore the conversion allowlist. See
|
| 550 |
+
ConversionOptions.user_requested.
|
| 551 |
+
|
| 552 |
+
Returns:
|
| 553 |
+
Either `f or the converted version of `f`.
|
| 554 |
+
"""
|
| 555 |
+
|
| 556 |
+
if is_autograph_artifact(f):
|
| 557 |
+
return f
|
| 558 |
+
f_wrapper = f
|
| 559 |
+
decorators, f = tf_decorator.unwrap(f)
|
| 560 |
+
|
| 561 |
+
# TODO(mdan): Grab features from context.
|
| 562 |
+
# Note: we pass the original context through to convert to properly handle the
|
| 563 |
+
# following scenario, which can be used inside TF implementations:
|
| 564 |
+
#
|
| 565 |
+
# ctx = ag_ctx.control_status_ctx()
|
| 566 |
+
# @function(autograph=False) # Low-level graph code
|
| 567 |
+
# def inner_fn():
|
| 568 |
+
# # The context is disabled here, but should be enabled in user user_fn
|
| 569 |
+
# tf_convert(user_fn, ctx=ctx)
|
| 570 |
+
if ctx.status == ag_ctx.Status.ENABLED:
|
| 571 |
+
wrapper_factory = convert(
|
| 572 |
+
recursive=True, user_requested=user_requested, conversion_ctx=ctx)
|
| 573 |
+
elif ctx.status == ag_ctx.Status.DISABLED:
|
| 574 |
+
wrapper_factory = do_not_convert
|
| 575 |
+
elif ctx.status == ag_ctx.Status.UNSPECIFIED:
|
| 576 |
+
if convert_by_default:
|
| 577 |
+
wrapper_factory = convert(
|
| 578 |
+
recursive=True, user_requested=user_requested, conversion_ctx=ctx)
|
| 579 |
+
else:
|
| 580 |
+
wrapper_factory = call_with_unspecified_conversion_status
|
| 581 |
+
else:
|
| 582 |
+
assert False, 'This switch contains all possible cases!'
|
| 583 |
+
wrapper = wrapper_factory(f)
|
| 584 |
+
|
| 585 |
+
if decorators:
|
| 586 |
+
wrapper = tf_decorator.rewrap(f_wrapper, f, wrapper)
|
| 587 |
+
|
| 588 |
+
return autograph_artifact(wrapper)
|
| 589 |
+
|
| 590 |
+
|
| 591 |
+
def call_with_unspecified_conversion_status(func):
|
| 592 |
+
"""Decorator that resets the conversion context to the unspecified status."""
|
| 593 |
+
|
| 594 |
+
def wrapper(*args, **kwargs):
|
| 595 |
+
with ag_ctx.ControlStatusCtx(status=ag_ctx.Status.UNSPECIFIED):
|
| 596 |
+
return func(*args, **kwargs)
|
| 597 |
+
|
| 598 |
+
if inspect.isfunction(func) or inspect.ismethod(func):
|
| 599 |
+
wrapper = functools.update_wrapper(wrapper, func)
|
| 600 |
+
|
| 601 |
+
return autograph_artifact(wrapper)
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
def _log_callargs(f, args, kwargs):
|
| 605 |
+
"""Logging helper."""
|
| 606 |
+
logging.log(2, 'Defaults of %s : %s', f, f.__defaults__)
|
| 607 |
+
logging.log(2, 'KW defaults of %s : %s', f, f.__kwdefaults__)
|
| 608 |
+
|
| 609 |
+
if kwargs is not None:
|
| 610 |
+
callargs = tf_inspect.getcallargs(f, *args, **kwargs)
|
| 611 |
+
else:
|
| 612 |
+
callargs = tf_inspect.getcallargs(f, *args)
|
| 613 |
+
|
| 614 |
+
formatted_callargs = '\n'.join(
|
| 615 |
+
' {}: {}'.format(k, v) for k, v in callargs.items())
|
| 616 |
+
logging.log(2, 'Calling %s with\n%s\n', f, formatted_callargs)
|
| 617 |
+
|
| 618 |
+
|
| 619 |
+
#
|
| 620 |
+
# Public API
|
| 621 |
+
#
|
| 622 |
+
|
| 623 |
+
|
| 624 |
+
@tf_export('autograph.experimental.do_not_convert')
|
| 625 |
+
def do_not_convert(func=None):
|
| 626 |
+
"""Decorator that suppresses the conversion of a function.
|
| 627 |
+
|
| 628 |
+
Args:
|
| 629 |
+
func: function to decorate.
|
| 630 |
+
|
| 631 |
+
Returns:
|
| 632 |
+
If `func` is not None, returns a `Callable` which is equivalent to
|
| 633 |
+
`func`, but is not converted by AutoGraph.
|
| 634 |
+
If `func` is None, returns a decorator that, when invoked with a
|
| 635 |
+
single `func` argument, returns a `Callable` equivalent to the
|
| 636 |
+
above case.
|
| 637 |
+
"""
|
| 638 |
+
if func is None:
|
| 639 |
+
return do_not_convert
|
| 640 |
+
|
| 641 |
+
def wrapper(*args, **kwargs):
|
| 642 |
+
with ag_ctx.ControlStatusCtx(status=ag_ctx.Status.DISABLED):
|
| 643 |
+
return func(*args, **kwargs)
|
| 644 |
+
|
| 645 |
+
if inspect.isfunction(func) or inspect.ismethod(func):
|
| 646 |
+
wrapper = functools.update_wrapper(wrapper, func)
|
| 647 |
+
|
| 648 |
+
return autograph_artifact(wrapper)
|
| 649 |
+
|
| 650 |
+
|
| 651 |
+
# TODO(mdan): Make private.
|
| 652 |
+
def convert(recursive=False,
|
| 653 |
+
optional_features=None,
|
| 654 |
+
user_requested=True,
|
| 655 |
+
conversion_ctx=ag_ctx.NullCtx()):
|
| 656 |
+
"""Decorator that compiles a function to use TensorFlow ops.
|
| 657 |
+
|
| 658 |
+
The decorator is dynamic - it recompiles the target whenever the decorated
|
| 659 |
+
function is called. This means the parameter values are known at conversion.
|
| 660 |
+
It also means that repeated calls with different types of parameters will be
|
| 661 |
+
correctly processed.
|
| 662 |
+
|
| 663 |
+
Args:
|
| 664 |
+
recursive: bool, whether to recursively convert any functions or classes
|
| 665 |
+
that the converted function may use.
|
| 666 |
+
optional_features: converted.Feature, allows toggling optional or
|
| 667 |
+
experimental features. When set to None, only the core features are
|
| 668 |
+
enabled.
|
| 669 |
+
user_requested: bool, whether this is a function that the user explicitly
|
| 670 |
+
asked to be converted. See ConversionOptions.user_requested.
|
| 671 |
+
conversion_ctx: Optional ag_ctx.ControlStatusCtx, the Autograph context in
|
| 672 |
+
which `f` is used.
|
| 673 |
+
|
| 674 |
+
Returns:
|
| 675 |
+
Callable, a decorator that converts the given function into an equivalent
|
| 676 |
+
function that uses TensorFlow ops.
|
| 677 |
+
"""
|
| 678 |
+
|
| 679 |
+
def decorator(f):
|
| 680 |
+
"""Decorator implementation."""
|
| 681 |
+
|
| 682 |
+
def wrapper(*args, **kwargs):
|
| 683 |
+
"""Wrapper that calls the converted version of f."""
|
| 684 |
+
options = converter.ConversionOptions(
|
| 685 |
+
recursive=recursive,
|
| 686 |
+
user_requested=user_requested,
|
| 687 |
+
optional_features=optional_features)
|
| 688 |
+
try:
|
| 689 |
+
with conversion_ctx:
|
| 690 |
+
return converted_call(f, args, kwargs, options=options)
|
| 691 |
+
except Exception as e: # pylint:disable=broad-except
|
| 692 |
+
if hasattr(e, 'ag_error_metadata'):
|
| 693 |
+
raise e.ag_error_metadata.to_exception(e)
|
| 694 |
+
else:
|
| 695 |
+
raise
|
| 696 |
+
|
| 697 |
+
if inspect.isfunction(f) or inspect.ismethod(f):
|
| 698 |
+
wrapper = functools.update_wrapper(wrapper, f)
|
| 699 |
+
|
| 700 |
+
decorated_wrapper = tf_decorator.make_decorator(f, wrapper)
|
| 701 |
+
return autograph_artifact(decorated_wrapper)
|
| 702 |
+
|
| 703 |
+
return decorator
|
| 704 |
+
|
| 705 |
+
|
| 706 |
+
# pylint:disable=line-too-long
|
| 707 |
+
@tf_export('autograph.to_graph', v1=[])
|
| 708 |
+
def to_graph(entity, recursive=True, experimental_optional_features=None):
|
| 709 |
+
"""Converts a Python entity into a TensorFlow graph.
|
| 710 |
+
|
| 711 |
+
Also see: `tf.autograph.to_code`, `tf.function`.
|
| 712 |
+
|
| 713 |
+
Unlike `tf.function`, `to_graph` is a low-level transpiler that converts
|
| 714 |
+
Python code to TensorFlow graph code. It does not implement any caching,
|
| 715 |
+
variable management or create any actual ops, and is best used where greater
|
| 716 |
+
control over the generated TensorFlow graph is desired. Another difference
|
| 717 |
+
from `tf.function` is that `to_graph` will not wrap the graph into a
|
| 718 |
+
TensorFlow function or a Python callable. Internally, `tf.function` uses
|
| 719 |
+
`to_graph`.
|
| 720 |
+
|
| 721 |
+
Example usage:
|
| 722 |
+
|
| 723 |
+
>>> def f(x):
|
| 724 |
+
... if x > 0:
|
| 725 |
+
... y = x * x
|
| 726 |
+
... else:
|
| 727 |
+
... y = -x
|
| 728 |
+
... return y
|
| 729 |
+
...
|
| 730 |
+
>>> converted_f = to_graph(f)
|
| 731 |
+
>>> x = tf.constant(2)
|
| 732 |
+
>>> converted_f(x) # converted_foo is like a TensorFlow Op.
|
| 733 |
+
<tf.Tensor: shape=(), dtype=int32, numpy=4>
|
| 734 |
+
|
| 735 |
+
Supported Python entities include:
|
| 736 |
+
* functions
|
| 737 |
+
* classes
|
| 738 |
+
* object methods
|
| 739 |
+
|
| 740 |
+
Functions are converted into new functions with converted code.
|
| 741 |
+
|
| 742 |
+
Classes are converted by generating a new class whose methods use converted
|
| 743 |
+
code.
|
| 744 |
+
|
| 745 |
+
Methods are converted into unbound function that have an additional first
|
| 746 |
+
argument called `self`.
|
| 747 |
+
|
| 748 |
+
For a tutorial, see the
|
| 749 |
+
[tf.function and AutoGraph guide](https://www.tensorflow.org/guide/function).
|
| 750 |
+
For more detailed information, see the
|
| 751 |
+
[AutoGraph reference documentation](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/g3doc/reference/index.md).
|
| 752 |
+
|
| 753 |
+
Args:
|
| 754 |
+
entity: Python callable or class to convert.
|
| 755 |
+
recursive: Whether to recursively convert any functions that the converted
|
| 756 |
+
function may call.
|
| 757 |
+
experimental_optional_features: `None`, a tuple of, or a single
|
| 758 |
+
`tf.autograph.experimental.Feature` value.
|
| 759 |
+
|
| 760 |
+
Returns:
|
| 761 |
+
Same as `entity`, the converted Python function or class.
|
| 762 |
+
|
| 763 |
+
Raises:
|
| 764 |
+
ValueError: If the entity could not be converted.
|
| 765 |
+
"""
|
| 766 |
+
try:
|
| 767 |
+
program_ctx = converter.ProgramContext(
|
| 768 |
+
options=converter.ConversionOptions(
|
| 769 |
+
recursive=recursive,
|
| 770 |
+
user_requested=True,
|
| 771 |
+
optional_features=experimental_optional_features))
|
| 772 |
+
return autograph_artifact(_convert_actual(entity, program_ctx))
|
| 773 |
+
except (ValueError, AttributeError, KeyError, NameError, AssertionError) as e:
|
| 774 |
+
logging.error(1, 'Error converting %s', entity, exc_info=True)
|
| 775 |
+
raise ConversionError('converting {}: {}: {}'.format(
|
| 776 |
+
entity, e.__class__.__name__, str(e)))
|
| 777 |
+
|
| 778 |
+
|
| 779 |
+
@tf_export(v1=['autograph.to_graph'])
|
| 780 |
+
def to_graph_v1(entity,
|
| 781 |
+
recursive=True,
|
| 782 |
+
arg_values=None,
|
| 783 |
+
arg_types=None,
|
| 784 |
+
experimental_optional_features=None):
|
| 785 |
+
"""Converts a Python entity into a TensorFlow graph.
|
| 786 |
+
|
| 787 |
+
Also see: `tf.autograph.to_code`, `tf.function`.
|
| 788 |
+
|
| 789 |
+
Unlike `tf.function`, `to_graph` is a low-level transpiler that converts
|
| 790 |
+
Python code to TensorFlow graph code. It does not implement any caching,
|
| 791 |
+
variable management or create any actual ops, and is best used where greater
|
| 792 |
+
control over the generated TensorFlow graph is desired. Another difference
|
| 793 |
+
from `tf.function` is that `to_graph` will not wrap the graph into a
|
| 794 |
+
TensorFlow function or a Python callable. Internally, `tf.function` uses
|
| 795 |
+
`to_graph`.
|
| 796 |
+
|
| 797 |
+
_Example Usage_
|
| 798 |
+
|
| 799 |
+
```python
|
| 800 |
+
def foo(x):
|
| 801 |
+
if x > 0:
|
| 802 |
+
y = x * x
|
| 803 |
+
else:
|
| 804 |
+
y = -x
|
| 805 |
+
return y
|
| 806 |
+
|
| 807 |
+
converted_foo = to_graph(foo)
|
| 808 |
+
|
| 809 |
+
x = tf.constant(1)
|
| 810 |
+
y = converted_foo(x) # converted_foo is a TensorFlow Op-like.
|
| 811 |
+
assert is_tensor(y)
|
| 812 |
+
```
|
| 813 |
+
|
| 814 |
+
Supported Python entities include:
|
| 815 |
+
* functions
|
| 816 |
+
* classes
|
| 817 |
+
* object methods
|
| 818 |
+
|
| 819 |
+
Functions are converted into new functions with converted code.
|
| 820 |
+
|
| 821 |
+
Classes are converted by generating a new class whose methods use converted
|
| 822 |
+
code.
|
| 823 |
+
|
| 824 |
+
Methods are converted into unbound function that have an additional first
|
| 825 |
+
argument called `self`.
|
| 826 |
+
|
| 827 |
+
Args:
|
| 828 |
+
entity: Python callable or class to convert.
|
| 829 |
+
recursive: Whether to recursively convert any functions that the converted
|
| 830 |
+
function may call.
|
| 831 |
+
arg_values: Deprecated.
|
| 832 |
+
arg_types: Deprecated.
|
| 833 |
+
experimental_optional_features: `None`, a tuple of, or a single
|
| 834 |
+
`tf.autograph.experimental.Feature` value.
|
| 835 |
+
|
| 836 |
+
Returns:
|
| 837 |
+
Same as `entity`, the converted Python function or class.
|
| 838 |
+
|
| 839 |
+
Raises:
|
| 840 |
+
ValueError: If the entity could not be converted.
|
| 841 |
+
"""
|
| 842 |
+
del arg_types
|
| 843 |
+
del arg_values
|
| 844 |
+
return to_graph(
|
| 845 |
+
entity,
|
| 846 |
+
recursive=recursive,
|
| 847 |
+
experimental_optional_features=experimental_optional_features)
|
| 848 |
+
|
| 849 |
+
|
| 850 |
+
@tf_export(v1=['autograph.to_code'])
|
| 851 |
+
def to_code_v1(entity,
|
| 852 |
+
recursive=True,
|
| 853 |
+
arg_values=None,
|
| 854 |
+
arg_types=None,
|
| 855 |
+
indentation=' ',
|
| 856 |
+
experimental_optional_features=None):
|
| 857 |
+
"""Returns the source code generated by AutoGraph, as a string.
|
| 858 |
+
|
| 859 |
+
Example usage:
|
| 860 |
+
|
| 861 |
+
>>> def f(x):
|
| 862 |
+
... if x < 0:
|
| 863 |
+
... x = -x
|
| 864 |
+
... return x
|
| 865 |
+
>>> tf.autograph.to_code(f)
|
| 866 |
+
"...def tf__f(x):..."
|
| 867 |
+
|
| 868 |
+
Also see: `tf.autograph.to_graph`.
|
| 869 |
+
|
| 870 |
+
Note: If a function has been decorated with `tf.function`, pass its
|
| 871 |
+
underlying Python function, rather than the callable that `tf.function
|
| 872 |
+
creates:
|
| 873 |
+
|
| 874 |
+
>>> @tf.function
|
| 875 |
+
... def f(x):
|
| 876 |
+
... if x < 0:
|
| 877 |
+
... x = -x
|
| 878 |
+
... return x
|
| 879 |
+
>>> tf.autograph.to_code(f.python_function)
|
| 880 |
+
"...def tf__f(x):..."
|
| 881 |
+
|
| 882 |
+
Args:
|
| 883 |
+
entity: Python callable or class.
|
| 884 |
+
recursive: Whether to recursively convert any functions that the converted
|
| 885 |
+
function may call.
|
| 886 |
+
arg_values: Deprecated.
|
| 887 |
+
arg_types: Deprecated.
|
| 888 |
+
indentation: Deprecated.
|
| 889 |
+
experimental_optional_features: `None`, a tuple of, or a single
|
| 890 |
+
`tf.autograph.experimental.Feature` value.
|
| 891 |
+
|
| 892 |
+
Returns:
|
| 893 |
+
The converted code as string.
|
| 894 |
+
"""
|
| 895 |
+
del arg_values
|
| 896 |
+
del arg_types
|
| 897 |
+
del indentation
|
| 898 |
+
return to_code(
|
| 899 |
+
entity,
|
| 900 |
+
recursive=recursive,
|
| 901 |
+
experimental_optional_features=experimental_optional_features)
|
| 902 |
+
|
| 903 |
+
|
| 904 |
+
@tf_export('autograph.to_code', v1=[])
|
| 905 |
+
def to_code(entity, recursive=True, experimental_optional_features=None):
|
| 906 |
+
"""Returns the source code generated by AutoGraph, as a string.
|
| 907 |
+
|
| 908 |
+
Example usage:
|
| 909 |
+
|
| 910 |
+
>>> def f(x):
|
| 911 |
+
... if x < 0:
|
| 912 |
+
... x = -x
|
| 913 |
+
... return x
|
| 914 |
+
>>> tf.autograph.to_code(f)
|
| 915 |
+
"...def tf__f(x):..."
|
| 916 |
+
|
| 917 |
+
Also see: `tf.autograph.to_graph`.
|
| 918 |
+
|
| 919 |
+
Note: If a function has been decorated with `tf.function`, pass its
|
| 920 |
+
underlying Python function, rather than the callable that `tf.function
|
| 921 |
+
creates:
|
| 922 |
+
|
| 923 |
+
>>> @tf.function
|
| 924 |
+
... def f(x):
|
| 925 |
+
... if x < 0:
|
| 926 |
+
... x = -x
|
| 927 |
+
... return x
|
| 928 |
+
>>> tf.autograph.to_code(f.python_function)
|
| 929 |
+
"...def tf__f(x):..."
|
| 930 |
+
|
| 931 |
+
Args:
|
| 932 |
+
entity: Python callable or class to convert.
|
| 933 |
+
recursive: Whether to recursively convert any functions that the converted
|
| 934 |
+
function may call.
|
| 935 |
+
experimental_optional_features: `None`, a tuple of, or a single
|
| 936 |
+
`tf.autograph.experimental.Feature` value.
|
| 937 |
+
|
| 938 |
+
Returns:
|
| 939 |
+
The converted code as string.
|
| 940 |
+
"""
|
| 941 |
+
source = tf_inspect.getsource(
|
| 942 |
+
to_graph(
|
| 943 |
+
entity,
|
| 944 |
+
recursive=recursive,
|
| 945 |
+
experimental_optional_features=experimental_optional_features))
|
| 946 |
+
return textwrap.dedent(source)
|
| 947 |
+
|
| 948 |
+
|
| 949 |
+
_TRANSPILER = PyToTF()
|
SwarmUI/dlbackend/ComfyUI/venv/lib/python3.10/site-packages/tensorflow/python/autograph/impl/conversion.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
# ==============================================================================
|
| 15 |
+
"""Core conversion logic, serves as main point of access."""
|
| 16 |
+
|
| 17 |
+
import functools
|
| 18 |
+
import inspect
|
| 19 |
+
import sys
|
| 20 |
+
import unittest
|
| 21 |
+
|
| 22 |
+
from tensorflow.python.autograph.core import config
|
| 23 |
+
from tensorflow.python.autograph.pyct import cache
|
| 24 |
+
from tensorflow.python.autograph.pyct import inspect_utils
|
| 25 |
+
from tensorflow.python.autograph.utils import ag_logging as logging
|
| 26 |
+
from tensorflow.python.eager.polymorphic_function import tf_method_target
|
| 27 |
+
from tensorflow.python.util import tf_inspect
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
_ALLOWLIST_CACHE = cache.UnboundInstanceCache()
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def _is_of_known_loaded_module(f, module_name):
|
| 34 |
+
mod = sys.modules.get(module_name, None)
|
| 35 |
+
if mod is None:
|
| 36 |
+
return False
|
| 37 |
+
if any(v is not None for v in mod.__dict__.values() if f is v):
|
| 38 |
+
return True
|
| 39 |
+
return False
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def _is_known_loaded_type(f, module_name, entity_name):
|
| 43 |
+
"""Tests whether the function or method is an instance of a known type."""
|
| 44 |
+
if (module_name not in sys.modules or
|
| 45 |
+
not hasattr(sys.modules[module_name], entity_name)):
|
| 46 |
+
return False
|
| 47 |
+
type_entity = getattr(sys.modules[module_name], entity_name)
|
| 48 |
+
if isinstance(f, type_entity):
|
| 49 |
+
# The method if of this type. Example:
|
| 50 |
+
#
|
| 51 |
+
# o = ClassType()
|
| 52 |
+
# function(o.method)()
|
| 53 |
+
return True
|
| 54 |
+
# Note: inspect is required here, to avoid unpacking tf.function decorators.
|
| 55 |
+
if inspect.ismethod(f):
|
| 56 |
+
# The unbound method if of this type. Example:
|
| 57 |
+
#
|
| 58 |
+
# class ClassType:
|
| 59 |
+
# @function
|
| 60 |
+
# def method(self):
|
| 61 |
+
# ...
|
| 62 |
+
# o = ClassType()
|
| 63 |
+
# o.method()
|
| 64 |
+
if isinstance(f.__func__, type_entity):
|
| 65 |
+
return True
|
| 66 |
+
return False
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def is_unsupported(o):
|
| 70 |
+
"""Checks whether an entity is supported by AutoGraph at all."""
|
| 71 |
+
|
| 72 |
+
# TODO(b/122265385): Remove this bypass.
|
| 73 |
+
if (_is_known_loaded_type(o, 'wrapt', 'FunctionWrapper') or
|
| 74 |
+
_is_known_loaded_type(o, 'wrapt', 'BoundFunctionWrapper')):
|
| 75 |
+
logging.warning(
|
| 76 |
+
'{} appears to be decorated by wrapt, which is not yet supported'
|
| 77 |
+
' by AutoGraph. The function will run as-is.'
|
| 78 |
+
' You may still apply AutoGraph before the wrapt decorator.'.format(o))
|
| 79 |
+
logging.log(2, 'Permanently allowed: %s: wrapt decorated', o)
|
| 80 |
+
return True
|
| 81 |
+
|
| 82 |
+
if _is_known_loaded_type(o, 'functools', '_lru_cache_wrapper'):
|
| 83 |
+
logging.log(2, 'Permanently allowed: %s: lru_cache', o)
|
| 84 |
+
return True
|
| 85 |
+
|
| 86 |
+
# Constructors are permanently allowed.
|
| 87 |
+
# TODO(mdan): Toggle as experimental feature instead.
|
| 88 |
+
# TODO(b/124016764): Remove this limitation.
|
| 89 |
+
if inspect_utils.isconstructor(o):
|
| 90 |
+
logging.log(2, 'Permanently allowed: %s: constructor', o)
|
| 91 |
+
return True
|
| 92 |
+
|
| 93 |
+
# Other built-in modules are permanently allowed.
|
| 94 |
+
# TODO(mdan): Figure out how to do this consistently for all stdlib modules.
|
| 95 |
+
if any(
|
| 96 |
+
_is_of_known_loaded_module(o, m)
|
| 97 |
+
for m in ('collections', 'pdb', 'copy', 'inspect', 're')):
|
| 98 |
+
logging.log(2, 'Permanently allowed: %s: part of builtin module', o)
|
| 99 |
+
return True
|
| 100 |
+
|
| 101 |
+
# Custom ops and kernels are also permanently allowed.
|
| 102 |
+
# See tensorflow.framework.load_library.
|
| 103 |
+
if (hasattr(o, '__module__') and
|
| 104 |
+
hasattr(o.__module__, '_IS_TENSORFLOW_PLUGIN')):
|
| 105 |
+
logging.log(2, 'Permanently allowed: %s: TensorFlow plugin', o)
|
| 106 |
+
return True
|
| 107 |
+
|
| 108 |
+
return False
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# TODO(mdan): allow_namedtuple_subclass should be hardcoded to True.
|
| 112 |
+
def is_allowlisted(
|
| 113 |
+
o, check_call_override=True, allow_namedtuple_subclass=False):
|
| 114 |
+
"""Checks whether an entity is allowed for use in graph mode.
|
| 115 |
+
|
| 116 |
+
Examples of allowed entities include all members of the tensorflow
|
| 117 |
+
package.
|
| 118 |
+
|
| 119 |
+
Args:
|
| 120 |
+
o: A Python entity.
|
| 121 |
+
check_call_override: Reserved for internal use. When set to `False`, it
|
| 122 |
+
disables the rule according to which classes are allowed if their
|
| 123 |
+
__call__ method is allowed.
|
| 124 |
+
allow_namedtuple_subclass: Reserved for internal use. When `True`,
|
| 125 |
+
namedtuple subclasses are not allowed.
|
| 126 |
+
|
| 127 |
+
Returns:
|
| 128 |
+
Boolean
|
| 129 |
+
"""
|
| 130 |
+
# TODO(b/120224672): Fix this.
|
| 131 |
+
if isinstance(o, functools.partial):
|
| 132 |
+
# tf_inspect.getmodule(functools.partial(...)) otherwise returns None since
|
| 133 |
+
# functools.partial objects do not have a __module__ attribute.
|
| 134 |
+
m = functools
|
| 135 |
+
else:
|
| 136 |
+
m = tf_inspect.getmodule(o)
|
| 137 |
+
|
| 138 |
+
# Examples of callables that lack a __module__ property include builtins.
|
| 139 |
+
if hasattr(m, '__name__'):
|
| 140 |
+
for rule in config.CONVERSION_RULES:
|
| 141 |
+
action = rule.get_action(m)
|
| 142 |
+
if action == config.Action.CONVERT:
|
| 143 |
+
logging.log(2, 'Not allowed: %s: %s', o, rule)
|
| 144 |
+
return False
|
| 145 |
+
elif action == config.Action.DO_NOT_CONVERT:
|
| 146 |
+
logging.log(2, 'Allowlisted: %s: %s', o, rule)
|
| 147 |
+
return True
|
| 148 |
+
|
| 149 |
+
# The check for __code__ below is because isgeneratorfunction crashes
|
| 150 |
+
# without one.
|
| 151 |
+
if hasattr(o, '__code__') and tf_inspect.isgeneratorfunction(o):
|
| 152 |
+
logging.log(2, 'Allowlisted: %s: generator functions are not converted', o)
|
| 153 |
+
return True
|
| 154 |
+
|
| 155 |
+
if (check_call_override and not tf_inspect.isclass(o) and
|
| 156 |
+
hasattr(o, '__call__')):
|
| 157 |
+
# Callable objects: allowed if their __call__ method is.
|
| 158 |
+
# The type check avoids infinite recursion around the __call__ method
|
| 159 |
+
# of function objects.
|
| 160 |
+
if (type(o) != type(o.__call__)) and is_allowlisted(o.__call__): # pylint: disable=unidiomatic-typecheck
|
| 161 |
+
logging.log(2, 'Allowlisted: %s: object __call__ allowed', o)
|
| 162 |
+
return True
|
| 163 |
+
|
| 164 |
+
owner_class = None
|
| 165 |
+
if tf_inspect.ismethod(o):
|
| 166 |
+
# Methods of allowed classes are also allowed, even if they are
|
| 167 |
+
# bound via user subclasses.
|
| 168 |
+
#
|
| 169 |
+
# For example, suppose `tf.Foo` has a method called `bar`, and `baz` is
|
| 170 |
+
# defined as below. `tf.Foo` is allowed. Then `baz.bar` is also
|
| 171 |
+
# allowed.
|
| 172 |
+
#
|
| 173 |
+
# class Custom(tf.Foo):
|
| 174 |
+
# pass
|
| 175 |
+
#
|
| 176 |
+
# baz = Custom()
|
| 177 |
+
#
|
| 178 |
+
# For the example above, if `Custom` did overload `bar`, then it would no
|
| 179 |
+
# longer be allowed.
|
| 180 |
+
|
| 181 |
+
owner_class = inspect_utils.getmethodclass(o)
|
| 182 |
+
if owner_class is tf_method_target.TfMethodTarget:
|
| 183 |
+
owner_class = o.__self__.target_class
|
| 184 |
+
if owner_class is not None:
|
| 185 |
+
if issubclass(owner_class, unittest.TestCase):
|
| 186 |
+
logging.log(2, 'Allowlisted: %s: method of TestCase subclass', o)
|
| 187 |
+
return True
|
| 188 |
+
|
| 189 |
+
owner_class = inspect_utils.getdefiningclass(o, owner_class)
|
| 190 |
+
if is_allowlisted(
|
| 191 |
+
owner_class,
|
| 192 |
+
check_call_override=False,
|
| 193 |
+
allow_namedtuple_subclass=True):
|
| 194 |
+
logging.log(2, 'Allowlisted: %s: owner is allowed %s', o,
|
| 195 |
+
owner_class)
|
| 196 |
+
return True
|
| 197 |
+
|
| 198 |
+
if inspect_utils.isnamedtuple(o):
|
| 199 |
+
# Due to the way they're constructed, namedtuple types cannot be converted
|
| 200 |
+
# because they don't expose source code. But we assume they are safe for
|
| 201 |
+
# graph mode since they are just containers.
|
| 202 |
+
if allow_namedtuple_subclass:
|
| 203 |
+
if not any(inspect_utils.isnamedtuple(base) for base in o.__bases__):
|
| 204 |
+
logging.log(2, 'Allowlisted: %s: named tuple', o)
|
| 205 |
+
return True
|
| 206 |
+
else:
|
| 207 |
+
logging.log(2, 'Allowlisted: %s: named tuple or subclass', o)
|
| 208 |
+
return True
|
| 209 |
+
|
| 210 |
+
logging.log(2, 'Not allowed: %s: default rule', o)
|
| 211 |
+
return False
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def is_in_allowlist_cache(entity, options):
|
| 215 |
+
try:
|
| 216 |
+
return _ALLOWLIST_CACHE.has(entity, options)
|
| 217 |
+
except TypeError:
|
| 218 |
+
# Catch-all for entities that are unhashable or don't allow weakrefs.
|
| 219 |
+
return False
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
def cache_allowlisted(entity, options):
|
| 223 |
+
try:
|
| 224 |
+
_ALLOWLIST_CACHE[entity][options] = True
|
| 225 |
+
except TypeError:
|
| 226 |
+
# Catch-all for entities that are unhashable or don't allow weakrefs.
|
| 227 |
+
pass
|