static */
| 2838 | } |
| 2839 | |
| 2840 | /* static */ StatusOr<Shape> ShapeInference::InferReshapeShape( |
| 2841 | const Shape& operand, absl::Span<const int64> dimensions, |
| 2842 | absl::Span<const int64> new_sizes, int64 inferred_dimension) { |
| 2843 | TF_RETURN_IF_ERROR(ExpectArray(operand, "reshape")); |
| 2844 | |
| 2845 | Shape inferred_shape = |
| 2846 | ShapeUtil::MakeShape(operand.element_type(), new_sizes); |
| 2847 | VLOG(3) << "Reshape inferred shape: " |
| 2848 | << ShapeUtil::HumanString(inferred_shape); |
| 2849 | |
| 2850 | if (ShapeUtil::ElementsIn(operand) != ShapeUtil::ElementsIn(inferred_shape)) { |
| 2851 | return InvalidArgument( |
| 2852 | "Reshape operation has mismatched element counts: from=%d (%s) " |
| 2853 | "to=%d (%s).", |
| 2854 | ShapeUtil::ElementsIn(operand), ShapeUtil::HumanString(operand), |
| 2855 | ShapeUtil::ElementsIn(inferred_shape), |
| 2856 | ShapeUtil::HumanString(inferred_shape)); |
| 2857 | } |
| 2858 | |
| 2859 | std::vector<int64> indices(operand.rank()); |
| 2860 | std::iota(indices.begin(), indices.end(), 0); |
| 2861 | if (dimensions.size() != operand.rank() || |
| 2862 | !std::is_permutation(dimensions.begin(), dimensions.end(), |
| 2863 | indices.begin())) { |
| 2864 | return InvalidArgument( |
| 2865 | "Reshape dimensions [%s] are not a permutation of the operand " |
| 2866 | "dimensions (operand shape is %s).", |
| 2867 | StrJoin(dimensions, ","), ShapeUtil::HumanString(operand)); |
| 2868 | } |
| 2869 | |
| 2870 | // Propagate dynamic dimension. |
| 2871 | auto common_factors = CommonFactors(operand.dimensions(), new_sizes); |
| 2872 | for (int64 input_dim = 0; input_dim < operand.rank(); ++input_dim) { |
| 2873 | if (!operand.is_dynamic_dimension(input_dim)) { |
| 2874 | continue; |
| 2875 | } |
| 2876 | |
| 2877 | string reshape_debug_str = absl::StrFormat( |
| 2878 | "output: %s, input: %s, input_dim: " |
| 2879 | "%lld", |
| 2880 | ShapeUtil::HumanString(inferred_shape), ShapeUtil::HumanString(operand), |
| 2881 | input_dim); |
| 2882 | |
| 2883 | int64 input_dim_start = -1; |
| 2884 | int64 input_dim_end = -1; |
| 2885 | int64 output_dim_start = -1; |
| 2886 | int64 output_dim_end = -1; |
| 2887 | // Find common_factors that the input_dim belongs to. |
| 2888 | for (int64 i = 0; i < common_factors.size() - 1; ++i) { |
| 2889 | auto start = common_factors[i]; |
| 2890 | auto end = common_factors[i + 1]; |
| 2891 | if (input_dim >= start.first && input_dim < end.first) { |
| 2892 | input_dim_start = start.first; |
| 2893 | input_dim_end = end.first; |
| 2894 | output_dim_start = start.second; |
| 2895 | output_dim_end = end.second; |
| 2896 | break; |
| 2897 | } |
nothing calls this directly
no test coverage detected