Esempio n. 1
0
def _copy_source(s, graph, op_map, handle_captures, inverse_captures,
                 base_graph):
  """Create a source in a graph based on a Tensor from a different graph.

  This function creates a placeholder analog of `s` in a graph with the
  following behavior:

  1) If s is a captured Tensor or Variable and handle_captures is set to True,
     simply capture it in the new graph as well.

  2) If s is a PlaceholderWithDefault whose default is a constant, preserve
     said default in the new graph.

  3) When applicable, copy resource variable metadata from `s` to the newly
     created placeholder.

  Args:
    s: The source of interest.
    graph: The destination graph.
    op_map: A dict mapping ops and tensors in the old graph to the new one.
    handle_captures: A boolean indicating whether to re-capture s in the new
      graph or simply create a vanilla placeholder.
    inverse_captures: A dict mapping s back to the Tensor or Variable that it
      captures.
    base_graph: The graph being copied from.
  """
  if handle_captures and s in inverse_captures:
    copied_placeholder = graph.capture(inverse_captures[s], name=s.op.name)
  elif s.op.type == "PlaceholderWithDefault" and _constant_inputs(s):
    # Copy the default value to the graph.
    default_value = s.op.inputs[0]
    unavailable_inputs, unavailable_control_inputs = _copy_non_source(
        op=default_value.op, graph=graph, op_map=op_map,
        base_graph=base_graph)
    if unavailable_inputs or unavailable_control_inputs:
      raise AssertionError(
          "Could not copy source node {} because it has inputs."
          .format(default_value))

    with ops.device(s.op.device):
      copied_placeholder = array_ops.placeholder_with_default(
          input=op_map[default_value], shape=s.shape, name=s.op.name)
  else:
    with ops.device(s.op.device):
      copied_placeholder = array_ops.placeholder(
          dtype=s.dtype, shape=s.shape, name=s.op.name)

  base_handle = resource_variable_ops.get_resource_handle_data(s)
  if base_handle.shape_and_type:
    resource_variable_ops._set_handle_shapes_and_types(  # pylint: disable=protected-access
        copied_placeholder,
        base_handle,
        graph_mode=True)

  op_map[s] = copied_placeholder
  # Add an entry for the op of the source tensor so that if there are any nodes
  # depending on that op via control dependencies it can work correctly.
  op_map[s.op] = copied_placeholder.op
Esempio n. 2
0
def _copy_source(s, graph, op_map, handle_captures, inverse_captures):
  """Create a source in a graph based on a Tensor from a different graph.

  This function creates a placeholder analog of `s` in a graph with the
  following behavior:

  1) If s is a captured Tensor or Variable and handle_captures is set to True,
     simply capture it in the new graph as well.

  2) If s is a PlaceholderWithDefault whose default is a constant, preserve
     said default in the new graph.

  3) When applicable, copy resource variable metadata from `s` to the newly
     created placeholder.

  Args:
    s: The source of interest.
    graph: The destination graph.
    op_map: A dict mapping ops and tensors in the old graph to the new one.
    handle_captures: A boolean indicating whether to re-capture s in the new
      graph or simply create a vanilla placeholder.
    inverse_captures: A dict mapping s back to the Tensor or Variable that it
      captures.
  """
  if handle_captures and s in inverse_captures:
    copied_placeholder = graph.capture(inverse_captures[s], name=s.op.name)
  elif s.op.type == "PlaceholderWithDefault" and _constant_inputs(s):
    # Copy the default value to the graph.
    default_value = s.op.inputs[0]
    unavailable_inputs, unavailable_control_inputs = _copy_non_source(
        op=default_value.op, graph=graph, op_map=op_map)
    if unavailable_inputs or unavailable_control_inputs:
      raise AssertionError(
          "Could not copy source node {} because it has inputs."
          .format(default_value))

    with ops.device(s.op.device):
      copied_placeholder = array_ops.placeholder_with_default(
          input=op_map[default_value], shape=s.shape, name=s.op.name)
  else:
    with ops.device(s.op.device):
      copied_placeholder = array_ops.placeholder(
          dtype=s.dtype, shape=s.shape, name=s.op.name)

  base_handle = resource_variable_ops.get_resource_handle_data(s)
  if base_handle.shape_and_type:
    resource_variable_ops._set_handle_shapes_and_types(  # pylint: disable=protected-access
        copied_placeholder,
        base_handle,
        graph_mode=True)

  op_map[s] = copied_placeholder
  # Add an entry for the op of the source tensor so that if there are any nodes
  # depending on that op via control dependencies it can work correctly.
  op_map[s.op] = copied_placeholder.op
Esempio n. 3
0
def _set_handle_data(func_graph, fdef):
  """Adds handle data for resource type inputs and outputs."""
  for tensor, arg_def in itertools.chain(
      zip(func_graph.inputs, fdef.signature.input_arg),
      zip(func_graph.outputs, fdef.signature.output_arg)):
    if arg_def.handle_data:
      shape_and_dtype = arg_def.handle_data[0]
      handle_data = cpp_shape_inference_pb2.CppShapeInferenceResult.HandleData()
      handle_data.is_set = True
      handle_data.shape_and_type.append(
          cpp_shape_inference_pb2.CppShapeInferenceResult.HandleShapeAndType(
              shape=shape_and_dtype.shape, dtype=shape_and_dtype.dtype))
      resource_variable_ops._set_handle_shapes_and_types(  # pylint: disable=protected-access
          tensor, handle_data, True)
def _set_handle_data(func_graph, fdef):
  """Adds handle data for resource type inputs and outputs."""
  # The shape of the handle itself is [], while the variable shape is
  # saved in `handle_data`. Previously, the shape of the resource handle
  # was set to `None`. Correct both shapes here.
  for tensor, arg_def in itertools.chain(
      zip(func_graph.inputs, fdef.signature.input_arg),
      zip(func_graph.outputs, fdef.signature.output_arg)):
    if arg_def.handle_data:
      tensor.set_shape([])

      shape_and_dtype = arg_def.handle_data[0]
      handle_data = cpp_shape_inference_pb2.CppShapeInferenceResult.HandleData()
      handle_data.is_set = True
      handle_data.shape_and_type.append(
          cpp_shape_inference_pb2.CppShapeInferenceResult.HandleShapeAndType(
              shape=shape_and_dtype.shape, dtype=shape_and_dtype.dtype))
      resource_variable_ops._set_handle_shapes_and_types(  # pylint: disable=protected-access
          tensor, handle_data, True)
Esempio n. 5
0
    def __init__(self,
                 shape,
                 local_replica_id,
                 initializer=None,
                 trainable=True,
                 use_hashtable=True,
                 name="EmbeddingVariable",
                 dtype=None,
                 key_dtype=None,
                 *args,
                 **kwargs):
        if (not isinstance(shape, list)) or (len(shape) != 2):
            raise ValueError("shape_per_gpu must be a list which represents: "+\
                             "[vocabulary_size_per_gpu, embedding_vector_size].")
        self.m_shape_per_gpu = TensorShape(shape)
        self.m_local_replica_id = local_replica_id
        self.m_initializer = initializer or InPlaceInitializer(
            name="random_uniform")
        if not isinstance(self.m_initializer, InPlaceInitializer):
            self.m_initializer = tf_initializers.get(self.m_initializer)
        self.m_trainable = trainable
        self.m_use_hashtable = use_hashtable
        self.m_embedding_layer = None
        self.m_dtype = dtype or dtypes.float32
        self.m_key_dtype = key_dtype or dtypes.int64
        # produce intial_value
        if isinstance(self.m_initializer, InPlaceInitializer):
            # TODO: serialize it
            self.m_initial_value = self.m_initializer.name
        else:
            self.m_initial_value = self.m_initializer(
                shape=self.m_shape_per_gpu, dtype=self.m_dtype)

        collections = [ops.GraphKeys.GLOBAL_VARIABLES]
        if trainable and ops.GraphKeys.TRAINABLE_VARIABLES not in collections:
            collections = list(collections) + [
                ops.GraphKeys.TRAINABLE_VARIABLES
            ]

        with ops.init_scope():
            self._in_graph_mode = not context.executing_eagerly()
            with ops.name_scope(name) as var_name_scope:
                # TODO: use regulare expression
                while var_name_scope[-1] == r"/":
                    var_name_scope = var_name_scope[:-1]
                var_name = var_name_scope
                self.m_var_name = var_name
                self.m_unique_id = "%s_%d" % (var_name, ops.uid())

                # attr = resource_variable_ops.attr_value_pb2.AttrValue(
                #     list=resource_variable_ops.attr_value_pb2.AttrValue.ListValue(
                #         s=[resource_variable_ops.compat.as_bytes("loc:@%s" % self.m_var_name)]))

                # with ops.get_default_graph()._attr_scope({"_class": attr}):
                with ops.NullContextmanager():
                    # m_handle is the handle to EmbeddingVariable, tf_handle is the handle to TF Var.
                    self.m_handle, self.tf_handle = kit_lib.create_var(
                        var_name=var_name,
                        dtype=self.m_dtype,
                        shape=self.m_shape_per_gpu)

                    if self._in_graph_mode:
                        with ops.name_scope("IsInitialized"):
                            self._is_initialized_op = ops.convert_to_tensor(
                                True)  # TODO: should not hard-writing???

                            if (isinstance(self.m_initial_value, ops.Tensor)
                                    and not self.m_initial_value.shape.
                                    is_compatible_with(self.m_shape_per_gpu)):
                                raise ValueError(
                                    "The initial value's shape (%s) is not compatible with "
                                    "the explicitly supplied `shape` argument (%s)."
                                    % (initial_value.shape,
                                       self.m_shape_per_gpu))

                            _init_op = kit_lib.assign_embedding_variable(
                                emb_var_handle=self.m_handle,
                                tf_var_handle=self.tf_handle,
                                var_name=var_name,
                                initial_value=self.m_initial_value,
                                local_replica_id=self.m_local_replica_id,
                                trainable=self.m_trainable,
                                shape=self.m_shape_per_gpu,
                                use_hashtable=self.m_use_hashtable,
                                dtype=self.m_dtype,
                                key_dtype=self.m_key_dtype)
                            self._initializer_op = control_flow_ops.group(
                                (_init_op))
                    else:
                        raise RuntimeError(
                            "Currently, EmbeddingVariable does not support Eager mode."
                        )

                    if not context.executing_eagerly():
                        ops.add_to_collections(collections, self)

            super(EmbeddingVariable, self).__init__(
                trainable=self.m_trainable,
                shape=self.m_shape_per_gpu,
                dtype=self.m_dtype,
                handle=self.m_handle,
                handle_name=var_name,
                distribute_strategy=get_strategy() if has_strategy() else None,
                synchronization=VariableSynchronization.NONE,
                aggregation=VariableAggregation.ONLY_FIRST_REPLICA,
                unique_id=self.m_unique_id,
                initializer_op=self._initializer_op,
                is_initialized_op=self._is_initialized_op,
                *args,
                **kwargs)
            handle_data = resource_variable_ops.cpp_shape_inference_pb2.CppShapeInferenceResult.HandleData(
            )
            handle_data.is_set = True
            handle_data.shape_and_type.append(
                resource_variable_ops.cpp_shape_inference_pb2.
                CppShapeInferenceResult.HandleShapeAndType(
                    shape=self.shape.as_proto(),
                    dtype=self.dtype.as_datatype_enum))
            resource_variable_ops._set_handle_shapes_and_types(
                self.m_handle,
                handle_data,
                graph_mode=False if context.executing_eagerly() else True)
            resource_variable_ops._set_handle_shapes_and_types(
                self.tf_handle,
                handle_data,
                graph_mode=False if context.executing_eagerly() else True)
Esempio n. 6
0
    def __init__(self,
                 shape,
                 local_replica_id,
                 initializer=None,
                 trainable=True,
                 use_hashtable=True,
                 name="EmbeddingVariable",
                 dtype=None,
                 key_dtype=None,
                 *args,
                 **kwargs):
        if (not isinstance(shape, list)) or (len(shape) != 2):
            raise ValueError("shape_per_gpu must be a list which represents: "+\
                             "[vocabulary_size_per_gpu, embedding_vector_size].")
        self.m_shape_per_gpu = TensorShape(shape)
        self.m_local_replica_id = local_replica_id
        self.m_initializer = initializer or InPlaceInitializer(name="random_uniform")
        if not isinstance(self.m_initializer, InPlaceInitializer):
            self.m_initializer = tf_initializers.get(self.m_initializer)
        self.m_trainable = trainable
        self.m_use_hashtable = use_hashtable
        self.m_embedding_layer = None
        self.m_dtype = dtype or dtypes.float32
        self.m_key_dtype = key_dtype or dtypes.int64
        # produce intial_value
        if isinstance(self.m_initializer, InPlaceInitializer):
            # TODO: serialize it
            self.m_initial_value = self.m_initializer.name
        else:
            self.m_initial_value = self.m_initializer(shape=self.m_shape_per_gpu, dtype=self.m_dtype)

        with ops.init_scope():
            with ops.name_scope(name):
                self.m_var_name = self._gen_unique_name(name)
                self.m_unique_id = "%s_%d" %(self.m_var_name, ops.uid())

                # m_handle is the handle to EmbeddingVariable, tf_handle is the handle to TF Var.
                self.m_handle, self.tf_handle = kit_lib.create_var(
                                            var_name=self.m_var_name,
                                            dtype=self.m_dtype,
                                            shape=self.m_shape_per_gpu)

                with ops.name_scope("IsInitialized"):
                    self._is_initialized_op = ops.convert_to_tensor(True)

                    if (isinstance(self.m_initial_value, ops.Tensor) and
                        not self.m_initial_value.shape.is_compatible_with(self.m_shape_per_gpu)):
                        raise ValueError("The initial value's shape (%s) is not compatible with "
                                         "the explicitly supplied `shape` argument (%s)." %
                                         (self.m_initial_value.shape, self.m_shape_per_gpu))

                    _init_op = kit_lib.assign_embedding_variable(emb_var_handle=self.m_handle,
                                                            tf_var_handle=self.tf_handle,
                                                            var_name=self.m_var_name,
                                                            initial_value=self.m_initial_value,
                                                            local_replica_id=self.m_local_replica_id,
                                                            trainable=self.m_trainable,
                                                            shape=self.m_shape_per_gpu,
                                                            use_hashtable=self.m_use_hashtable,
                                                            dtype=self.m_dtype,
                                                            key_dtype=self.m_key_dtype)
                    self._initializer_op = control_flow_ops.group((_init_op))

            super(EmbeddingVariable, self).__init__(trainable=self.m_trainable,
                                                    shape=self.m_shape_per_gpu,
                                                    dtype=self.m_dtype,
                                                    handle=self.m_handle,
                                                    handle_name=self.m_var_name,
                                                    distribute_strategy=get_strategy() if has_strategy() else None,
                                                    synchronization=VariableSynchronization.NONE,
                                                    aggregation=VariableAggregation.ONLY_FIRST_REPLICA,
                                                    unique_id=self.m_unique_id,
                                                    *args, **kwargs)

            handle_data = resource_variable_ops.cpp_shape_inference_pb2.CppShapeInferenceResult.HandleData()
            handle_data.is_set = True
            handle_data.shape_and_type.append(
                resource_variable_ops.cpp_shape_inference_pb2.CppShapeInferenceResult.HandleShapeAndType(
                    shape=self.shape.as_proto(), dtype=self.dtype.as_datatype_enum))
            resource_variable_ops._set_handle_shapes_and_types(self.m_handle, handle_data, 
                graph_mode=False if context.executing_eagerly() else True)
            resource_variable_ops._set_handle_shapes_and_types(self.tf_handle, handle_data, 
                graph_mode=False if context.executing_eagerly() else True)