(self, args, kwargs)
| 314 | self._first_call = True |
| 315 | |
| 316 | def _call_func(self, args, kwargs): |
| 317 | try: |
| 318 | if self._variables_created: |
| 319 | vars_at_start = len( |
| 320 | ops.get_collection_ref(ops.GraphKeys.GLOBAL_VARIABLES)) |
| 321 | trainable_at_start = len( |
| 322 | ops.get_collection_ref(ops.GraphKeys.TRAINABLE_VARIABLES)) |
| 323 | |
| 324 | result = self._func(*args, **kwargs) |
| 325 | |
| 326 | # Variables were previously created, implying this is not the first |
| 327 | # time the template has been called. Check to make sure that no new |
| 328 | # trainable variables were created this time around. |
| 329 | trainable_variables = ops.get_collection_ref( |
| 330 | ops.GraphKeys.TRAINABLE_VARIABLES) |
| 331 | |
| 332 | # If a variable that we intend to train is created as a side effect |
| 333 | # of creating a template, then that is almost certainly an error. |
| 334 | if trainable_at_start != len(trainable_variables): |
| 335 | raise ValueError("Trainable variable created when calling a template " |
| 336 | "after the first time, perhaps you used tf.Variable " |
| 337 | "when you meant tf.get_variable: %s" % |
| 338 | (trainable_variables[trainable_at_start:],)) |
| 339 | |
| 340 | # Non-trainable tracking variables are a legitimate reason why a new |
| 341 | # variable would be created, but it is a relatively advanced use-case, |
| 342 | # so log it. |
| 343 | variables = ops.get_collection_ref(ops.GraphKeys.GLOBAL_VARIABLES) |
| 344 | if vars_at_start != len(variables): |
| 345 | logging.info( |
| 346 | "New variables created when calling a template after " |
| 347 | "the first time, perhaps you used tf.Variable when you " |
| 348 | "meant tf.get_variable: %s", variables[vars_at_start:]) |
| 349 | elif self._first_call: |
| 350 | self._first_call = False |
| 351 | try: |
| 352 | # The first time we run, restore variables if necessary (via |
| 353 | # Trackable). |
| 354 | with trackable_util.capture_dependencies(template=self): |
| 355 | result = self._func(*args, **kwargs) |
| 356 | except: |
| 357 | self._first_call = True |
| 358 | raise |
| 359 | self._variables_created = True |
| 360 | else: # We are calling the template in parallel from another thread. |
| 361 | result = self._func(*args, **kwargs) |
| 362 | return result |
| 363 | except Exception as exc: |
| 364 | # Reraise the exception, but append the original definition to the |
| 365 | # trace. |
| 366 | args = exc.args |
| 367 | if not args: |
| 368 | arg0 = "" |
| 369 | else: |
| 370 | arg0 = args[0] |
| 371 | trace = "".join( |
| 372 | _skip_common_stack_elements(self._stacktrace, |
| 373 | traceback.format_stack())) |
no test coverage detected