tensorflow/core/common_runtime/shape_refiner.cc
// Runs shape inference for the given node using the given ShapeRefiner.
// The node must be a sub-node of a function node and the outer_context is
// the inference context of that function node in the outer graph.
Runs shape inference for the given node using the given ShapeRefiner.
The node must be a sub-node of a function node and the outer_context is
the inference context of that function node in the outer graph.
Runs shape inference for the given node using the given ShapeRefiner . The node must be a sub - node of a function node and the outer_context is the inference context of that function node in the outer graph .
Status ShapeRefiner::InferShapesForFunctionSubNode(
    const Node* node, InferenceContext* outer_context) {
  TF_RETURN_IF_ERROR(AddNodeInternal(node, outer_context));
  InferenceContext* node_context = CHECK_NOTNULL(GetContext(node));
  if (StringPiece(node->type_string()) == kArgOp) {
    int index;
    TF_RETURN_IF_ERROR(GetNodeAttr(AttrSlice(node->def()), "index", &index));
    if (index < 0 || outer_context->num_inputs() <= index) {
      return errors::Internal(
          "Function instantiation included invalid input index: ", index,
          " not in [0, ", outer_context->num_inputs(), ").");
    }
    if (outer_context->input(index).SameHandle(ShapeHandle())) {
      VLOG(1) << "Function instantiation has undefined input shape at "
              << "index: " << index << " in the outer inference context.";
      node_context->set_output(0, node_context->UnknownShape());
    } else {
      node_context->set_output(0, outer_context->input(index));
    }
    auto* resource = outer_context->input_handle_shapes_and_types(index);
    if (resource) {
      node_context->set_output_handle_shapes_and_types(0, *resource);
    }
  } else if (StringPiece(node->type_string()) == kRetvalOp) {
    int index;
    TF_RETURN_IF_ERROR(GetNodeAttr(AttrSlice(node->def()), "index", &index));
    if (index < 0 || outer_context->num_outputs() <= index) {
      return errors::Internal(
          "Function instantiation included invalid output index: ", index,
          " not in [0, ", outer_context->num_outputs(), ").");
    }
    ShapeHandle handle;
    TensorShapeProto proto;
    node_context->ShapeHandleToProto(node_context->input(0), &proto);
    TF_RETURN_IF_ERROR(outer_context->MakeShapeFromShapeProto(proto, &handle));
    outer_context->set_output(index, handle);
    const std::vector<ShapeAndType>* resource =
        node_context->input_handle_shapes_and_types(0);
    if (resource) {
      std::vector<ShapeAndType> copied_shapes_and_types;
      for (auto& shape_and_type : *resource) {
        ShapeHandle handle;
        TensorShapeProto proto;
        node_context->ShapeHandleToProto(shape_and_type.shape, &proto);
        TF_RETURN_IF_ERROR(
            outer_context->MakeShapeFromShapeProto(proto, &handle));
        copied_shapes_and_types.push_back(
            ShapeAndType(handle, shape_and_type.dtype, shape_and_type.type));
      }
      outer_context->set_output_handle_shapes_and_types(
          index, copied_shapes_and_types);
    }
  }
  return Status::OK();
}
Status ShapeRefiner :: InferShapesForFunctionSubNode ( const Node * node , InferenceContext * outer_context ) { TF_RETURN_IF_ERROR ( AddNodeInternal ( node , outer_context ) ) ; InferenceContext * node_context = CHECK_NOTNULL ( GetContext ( node ) ) ; if ( StringPiece ( node -> type_string ( ) ) == kArgOp ) { int index ; TF_RETURN_IF_ERROR ( GetNodeAttr ( AttrSlice ( node -> def ( ) ) , " " , & index ) ) ; if ( index < 0 || outer_context -> num_inputs ( ) <= index ) { return errors :: Internal ( " " , index , " " , outer_context -> num_inputs ( ) , " " ) ; } if ( outer_context -> input ( index ) . SameHandle ( ShapeHandle ( ) ) ) { VLOG ( 1 ) << " " << " " << index << " " ; node_context -> set_output ( 0 , node_context -> UnknownShape ( ) ) ; } else { node_context -> set_output ( 0 , outer_context -> input ( index ) ) ; } auto * resource = outer_context -> input_handle_shapes_and_types ( index ) ; if ( resource ) { node_context -> set_output_handle_shapes_and_types ( 0 , * resource ) ; } } else if ( StringPiece ( node -> type_string ( ) ) == kRetvalOp ) { int index ; TF_RETURN_IF_ERROR ( GetNodeAttr ( AttrSlice ( node -> def ( ) ) , " " , & index ) ) ; if ( index < 0 || outer_context -> num_outputs ( ) <= index ) { return errors :: Internal ( " " , index , " " , outer_context -> num_outputs ( ) , " " ) ; } ShapeHandle handle ; TensorShapeProto proto ; node_context -> ShapeHandleToProto ( node_context -> input ( 0 ) , & proto ) ; TF_RETURN_IF_ERROR ( outer_context -> MakeShapeFromShapeProto ( proto , & handle ) ) ; outer_context -> set_output ( index , handle ) ; const std :: vector < ShapeAndType > * resource = node_context -> input_handle_shapes_and_types ( 0 ) ; if ( resource ) { std :: vector < ShapeAndType > copied_shapes_and_types ; for ( auto & shape_and_type : * resource ) { ShapeHandle handle ; TensorShapeProto proto ; node_context -> ShapeHandleToProto ( shape_and_type . shape , & proto ) ; TF_RETURN_IF_ERROR ( outer_context -> MakeShapeFromShapeProto ( proto , & handle ) ) ; copied_shapes_and_types . push_back ( ShapeAndType ( handle , shape_and_type . dtype , shape_and_type . type ) ) ; } outer_context -> set_output_handle_shapes_and_types ( index , copied_shapes_and_types ) ; } } return Status :: OK ( ) ; }
Runs shape inference for the given node using the given ShapeRefiner.
Runs shape inference for the given node using the given ShapeRefiner .
// Handle special node: function input. // Shapes for these nodes are provided in the outer inference // context. // TODO(b/134547156): TEMPORARY WORKAROUND. If input shape handle is not set // in outer context, set _Arg node output shape to unknown. // Handle special node: function output. // Shapes inferred for these nodes go into the outer inference // context. // outer_context outlives node_context, therefore we need to create // a new shape handle owned by outer_context instead. // `ShapesAndType`s contain `ShapeHandle`s.  These `ShapeHandle`s point // to `Shape`s that are owned by a different inference context too.  We // need to copy them to the outer context to prevent them from being // destroyed before they are used.