def args_to_matching_eager(l, ctx, allowed_dtypes, default_dtype=None): """Convert sequence `l` to eager same-type Tensors.""" if (not l) and (default_dtype is not None): return default_dtype, [] # List is empty; assume default dtype. EagerTensor = ops.EagerTensor # pylint: disable=invalid-name for x in l: if not isinstance(x, EagerTensor): break else: # note: intentional for-else return l[0]._datatype_enum(), l # pylint: disable=protected-access # Is some input already a Tensor with a dtype? dtype = None for t in l: if isinstance(t, EagerTensor): dtype = t.dtype break if dtype is None: # Infer a dtype based on the first value, and use that dtype for the # remaining values. ret = [] for t in l: tensor = None # First see if we can get a valid dtype with the default conversion # and see if it matches an allowed dtypes. Some ops like ConcatV2 may # not list allowed dtypes, in which case we should skip this. if dtype is None and allowed_dtypes: tensor = ops.convert_to_tensor(t, ctx=ctx) # If we did not match an allowed dtype, try again with the default # dtype. This could be because we have an empty tensor and thus we # picked the wrong type. if tensor.dtype not in allowed_dtypes: tensor = None if tensor is None: tensor = ops.convert_to_tensor(t, dtype, preferred_dtype=default_dtype, ctx=ctx) ret.append(tensor) if dtype is None: dtype = tensor.dtype else: ret = [ops.convert_to_tensor(t, dtype, ctx=ctx) for t in l] # TODO(slebedev): consider removing this as it leaks a Keras concept. # pylint: disable=protected-access keras_symbolic_tensors = [ x for x in ret if ops._is_keras_symbolic_tensor(x) ] if keras_symbolic_tensors: raise core._SymbolicException( "Using symbolic output of a Keras layer during eager execution " "{}".format(keras_symbolic_tensors)) # pylint: enable=protected-access return dtype.as_datatype_enum, ret
def execute_with_cancellation(op_name, num_outputs, inputs, attrs, ctx, cancellation_manager, name=None): """Execute a TensorFlow operation. Args: op_name: Name of the TensorFlow operation (see REGISTER_OP in C++ code) to execute. num_outputs: The number of outputs of the operation to fetch. (Explicitly provided instead of being inferred for performance reasons). inputs: A list of inputs to the operation. Each entry should be a Tensor, or a value which can be passed to the Tensor constructor to create one. attrs: A tuple with alternating string attr names and attr values for this operation. ctx: The value of context.context(). cancellation_manager: a `CancellationManager` object that can be used to cancel the operation. name: Customized name for the operation. Returns: List of output Tensor objects. The list is empty if there are no outputs Raises: An exception on error. """ device_name = ctx.device_name # pylint: disable=protected-access try: ctx.ensure_initialized() tensors = pywrap_tfe.TFE_Py_ExecuteCancelable(ctx._handle, device_name, op_name, inputs, attrs, cancellation_manager._impl, num_outputs) except core._NotOkStatusException as e: if name is not None: message = e.message + " name: " + name else: message = e.message six.raise_from(core._status_to_exception(e.code, message), None) except TypeError as e: keras_symbolic_tensors = [ x for x in inputs if ops._is_keras_symbolic_tensor(x) ] if keras_symbolic_tensors: raise core._SymbolicException( "Inputs to eager execution function cannot be Keras symbolic " "tensors, but found {}".format(keras_symbolic_tensors)) raise e # pylint: enable=protected-access return tensors
def args_to_matching_eager(l, ctx, default_dtype=None): """Convert sequence `l` to eager same-type Tensors.""" if (not l) and (default_dtype is not None): return default_dtype, [] # List is empty; assume default dtype. EagerTensor = ops.EagerTensor # pylint: disable=invalid-name for x in l: if not isinstance(x, EagerTensor): break else: # note: intentional for-else return l[0]._datatype_enum(), l # pylint: disable=protected-access # TODO(josh11b): Could we do a better job if we also passed in the # allowed dtypes when that was known? # Is some input already a Tensor with a dtype? dtype = None for t in l: if isinstance(t, EagerTensor): dtype = t.dtype break if dtype is None: # Infer a dtype based on the first value, and use that dtype for the # remaining values. ret = [] for t in l: ret.append( ops.convert_to_tensor(t, dtype, preferred_dtype=default_dtype, ctx=ctx)) if dtype is None: dtype = ret[-1].dtype else: ret = [ops.convert_to_tensor(t, dtype, ctx=ctx) for t in l] # TODO(slebedev): consider removing this as it leaks a Keras concept. # pylint: disable=protected-access keras_symbolic_tensors = [ x for x in ret if ops._is_keras_symbolic_tensor(x) ] if keras_symbolic_tensors: raise core._SymbolicException( "Using symbolic output of a Keras layer during eager execution " "{}".format(keras_symbolic_tensors)) # pylint: enable=protected-access return dtype.as_datatype_enum, ret