Fill in default values for grad_ys. Args: grad_ys: List of gradients, can contain None. ys: List of tensors. colocate_gradients_with_ops: If True, try colocating gradients with the corresponding op. gradient_uid: A unique identifier within the graph indicating which in
(grad_ys,
ys,
colocate_gradients_with_ops,
gradient_uid="__unsupported__")
| 137 | |
| 138 | |
| 139 | def _DefaultGradYs(grad_ys, |
| 140 | ys, |
| 141 | colocate_gradients_with_ops, |
| 142 | gradient_uid="__unsupported__"): |
| 143 | """Fill in default values for grad_ys. |
| 144 | |
| 145 | Args: |
| 146 | grad_ys: List of gradients, can contain None. |
| 147 | ys: List of tensors. |
| 148 | colocate_gradients_with_ops: If True, try colocating gradients with |
| 149 | the corresponding op. |
| 150 | gradient_uid: A unique identifier within the graph indicating |
| 151 | which invocation of gradients is being executed. Used to cluster |
| 152 | ops for compilation. |
| 153 | |
| 154 | Returns: |
| 155 | A list of gradients to use, without None. |
| 156 | |
| 157 | Raises: |
| 158 | ValueError: If sizes of gradients and inputs don't match |
| 159 | TypeError: If type of any gradient is not valid for its input. |
| 160 | """ |
| 161 | if len(grad_ys) != len(ys): |
| 162 | raise ValueError("Passed %d grad_ys for %d ys" % (len(grad_ys), len(ys))) |
| 163 | grad_ys = ops.convert_n_to_tensor_or_indexed_slices(grad_ys, name="grad_y") |
| 164 | new_grad_ys = [] |
| 165 | for i, (y, grad_y) in enumerate(zip(ys, grad_ys)): |
| 166 | with _maybe_colocate_with(y.op, gradient_uid, colocate_gradients_with_ops): |
| 167 | if grad_y is None: |
| 168 | if y.dtype.is_complex: |
| 169 | raise TypeError( |
| 170 | "Gradients of complex tensors must set grad_ys (y.dtype = %r)" % |
| 171 | y.dtype) |
| 172 | new_grad_ys.append( |
| 173 | array_ops.fill( |
| 174 | array_ops.shape(y), |
| 175 | constant_op.constant(1, dtype=y.dtype, name="grad_ys_%d" % i))) |
| 176 | continue |
| 177 | if y.dtype.is_floating or y.dtype.is_integer: |
| 178 | if not grad_y.dtype.is_floating and not grad_y.dtype.is_integer: |
| 179 | raise TypeError( |
| 180 | "Gradient type %s generated for real or " |
| 181 | "integer-valued tensor %s with type %s must be " |
| 182 | "real or integer" % (dtypes.as_dtype(grad_y.dtype).name, y, |
| 183 | dtypes.as_dtype(y.dtype).name)) |
| 184 | elif y.dtype.is_complex: |
| 185 | if not grad_y.dtype.is_complex: |
| 186 | raise TypeError( |
| 187 | "Gradient type %s generated for complex-valued " |
| 188 | "tensor %s with type %s must be real" % (dtypes.as_dtype( |
| 189 | grad_y.dtype).name, y, dtypes.as_dtype(y.dtype).name)) |
| 190 | elif y.dtype == dtypes.variant: |
| 191 | if grad_y.dtype != dtypes.variant: |
| 192 | raise TypeError( |
| 193 | "Gradient type %s generated for variant " |
| 194 | "tensor %s with type %s must be variant" % (dtypes.as_dtype( |
| 195 | grad_y.dtype).name, y, dtypes.as_dtype(y.dtype).name)) |
| 196 | elif y.dtype == dtypes.resource: |
no test coverage detected