()
| 659 | name = name if name is not None else self.get_name() |
| 660 | grads_and_vars = tuple(grads_and_vars) # Make sure repeat iteration works. |
| 661 | def apply_fn(): |
| 662 | # No DistributionStrategy case. |
| 663 | if not grads_and_vars: |
| 664 | raise ValueError("No variables provided.") |
| 665 | converted_grads_and_vars = [] |
| 666 | for g, v in grads_and_vars: |
| 667 | if g is not None: |
| 668 | try: |
| 669 | # Convert the grad to Tensor or IndexedSlices if necessary. |
| 670 | g = ops.convert_to_tensor_or_indexed_slices(g) |
| 671 | except TypeError: |
| 672 | raise TypeError( |
| 673 | "Gradient must be convertible to a Tensor" |
| 674 | " or IndexedSlices, or None: %s" % g) |
| 675 | if not isinstance(g, (ops.Tensor, ops.IndexedSlices)): |
| 676 | raise TypeError( |
| 677 | "Gradient must be a Tensor, IndexedSlices, or None: %s" % g) |
| 678 | p = _get_processor(v) |
| 679 | converted_grads_and_vars.append((g, v, p)) |
| 680 | |
| 681 | converted_grads_and_vars = tuple(converted_grads_and_vars) |
| 682 | var_list = [v for g, v, _ in converted_grads_and_vars if g is not None] |
| 683 | if not var_list: |
| 684 | raise ValueError("No gradients provided for any variable: %s." % |
| 685 | ([str(v) for _, v, _ in converted_grads_and_vars],)) |
| 686 | with ops.init_scope(): |
| 687 | self._create_slots(var_list) |
| 688 | update_ops = [] |
| 689 | with ops.name_scope(name, self._name) as sname: |
| 690 | self._prepare() |
| 691 | for grad, var, processor in converted_grads_and_vars: |
| 692 | if grad is None: |
| 693 | continue |
| 694 | # We colocate all ops created in _apply_dense or _apply_sparse |
| 695 | # on the same device as the variable. |
| 696 | # TODO(apassos): figure out how to get the variable name here. |
| 697 | if (context.executing_eagerly() or |
| 698 | isinstance(var, resource_variable_ops.BaseResourceVariable) |
| 699 | and not var._in_graph_mode): # pylint: disable=protected-access |
| 700 | scope_name = "" |
| 701 | else: |
| 702 | scope_name = var.op.name |
| 703 | with ops.name_scope("update_" + scope_name), ops.colocate_with(var): |
| 704 | update_ops.append(processor.update_op(self, grad)) |
| 705 | if (not context.executing_eagerly()) and isinstance(grad, ops.IndexedSlices): |
| 706 | var._is_sparse = True |
| 707 | update_ops.append(gen_io_ops.record_sparse_indices(grad.indices, var_name=scope_name)) |
| 708 | for slot_name in self.get_slot_names(): |
| 709 | slot = self.get_slot(var, slot_name) |
| 710 | slot._is_sparse = True |
| 711 | update_ops.append(gen_io_ops.record_sparse_indices(grad.indices, var_name=slot.op.name)) |
| 712 | if global_step is None: |
| 713 | apply_updates = self._finish(update_ops, sname) |
| 714 | else: |
| 715 | with ops.control_dependencies([self._finish(update_ops, "update")]): |
| 716 | with ops.colocate_with(global_step): |
| 717 | if isinstance(global_step, resource_variable_ops.ResourceVariable): |
| 718 | # TODO(apassos): the implicit read in assign_add is slow; consider |
nothing calls this directly
no test coverage detected