Create op in XLACompileContext and notifies outer context recursively.
(self, op)
| 181 | return internal_control_inputs, external_control_inputs |
| 182 | |
| 183 | def AddOp(self, op): |
| 184 | """Create op in XLACompileContext and notifies outer context recursively.""" |
| 185 | # pylint: disable=protected-access |
| 186 | if op.type in _BLACKLISTED_OPS: |
| 187 | logging.error( |
| 188 | 'Operation of type %s (%s) is not supported in XLA. Execution will ' |
| 189 | 'fail if this op is used in the graph. ', op.type, op.name) |
| 190 | |
| 191 | # TODO(ycao): Automatically disable summaries instead of reporting them. |
| 192 | if op.type in _UNSUPPORTED_OPS: |
| 193 | self._unsupported_ops.append(op) |
| 194 | |
| 195 | if any(x.dtype._is_ref_dtype for x in op.inputs): |
| 196 | raise NotImplementedError( |
| 197 | 'Non-resource Variables are not supported inside XLA computations ' |
| 198 | '(operator name: %s)' % op.name) |
| 199 | |
| 200 | if _XLA_COMPILE_ATTR in op.node_def.attr: |
| 201 | raise ValueError('XLA compiled computations cannot be nested, (operator ' |
| 202 | 'name: %s)' % op.name) |
| 203 | |
| 204 | op._set_attr( |
| 205 | _XLA_COMPILE_ATTR, attr_value_pb2.AttrValue(s=self._name_as_bytes)) |
| 206 | |
| 207 | op.graph.prevent_feeding(op) |
| 208 | op.graph.prevent_fetching(op) |
| 209 | |
| 210 | # Remove any control edges from outer control flow contexts. These may cause |
| 211 | # mismatched frame errors. An example is when one of op's inputs is |
| 212 | # generated in a different While control flow context. |
| 213 | (internal_control_inputs, |
| 214 | external_control_inputs) = self._RemoveExternalControlEdges(op) |
| 215 | |
| 216 | if not op.inputs: |
| 217 | # Add a control edge from the control pivot to this op. |
| 218 | if not internal_control_inputs: |
| 219 | # pylint: disable=protected-access |
| 220 | op._add_control_input(self._pivot) |
| 221 | # pylint: enable=protected-access |
| 222 | else: |
| 223 | for index in xrange(len(op.inputs)): |
| 224 | x = op.inputs[index] |
| 225 | real_x = self.AddValue(x) |
| 226 | if real_x is not x: |
| 227 | op._update_input(index, real_x) # pylint: disable=protected-access |
| 228 | |
| 229 | if external_control_inputs: |
| 230 | # Use an identity to pull control inputs as data inputs. Note that we |
| 231 | # ignore ops which don't have outputs. TODO(phawkins): fix that. |
| 232 | with ops.control_dependencies(None): |
| 233 | self.Enter() |
| 234 | external_control_inputs = [ |
| 235 | array_ops.identity(x.outputs[0]).op |
| 236 | for x in external_control_inputs |
| 237 | if x.outputs |
| 238 | ] |
| 239 | self.Exit() |
| 240 | # pylint: disable=protected-access |
no test coverage detected