| 1122 | } |
| 1123 | |
| 1124 | Status FusedBatchNormShape(shape_inference::InferenceContext* c) { |
| 1125 | string data_format_str; |
| 1126 | TF_RETURN_IF_ERROR(c->GetAttr("data_format", &data_format_str)); |
| 1127 | TensorFormat data_format; |
| 1128 | if (!FormatFromString(data_format_str, &data_format)) { |
| 1129 | return errors::InvalidArgument("Invalid data format string: ", |
| 1130 | data_format_str); |
| 1131 | } |
| 1132 | const int rank = |
| 1133 | (data_format_str == "NDHWC" or data_format_str == "NCDHW") ? 5 : 4; |
| 1134 | ShapeHandle x; |
| 1135 | TF_RETURN_IF_ERROR(c->WithRank(c->input(0), rank, &x)); |
| 1136 | |
| 1137 | bool is_training; |
| 1138 | TF_RETURN_IF_ERROR(c->GetAttr("is_training", &is_training)); |
| 1139 | |
| 1140 | float exponential_avg_factor; |
| 1141 | if (!c->GetAttr("exponential_avg_factor", &exponential_avg_factor).ok()) { |
| 1142 | exponential_avg_factor = 1.0f; // default value |
| 1143 | } |
| 1144 | int number_inputs = (is_training && exponential_avg_factor == 1.0f) ? 3 : 5; |
| 1145 | |
| 1146 | int channel_dim_index = GetTensorFeatureDimIndex(rank, data_format); |
| 1147 | DimensionHandle channel_dim = c->Dim(x, channel_dim_index); |
| 1148 | |
| 1149 | // covers scale, offset, and if is_training is false, mean, variance |
| 1150 | for (int i = 1; i < number_inputs; ++i) { |
| 1151 | ShapeHandle vec; |
| 1152 | TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 1, &vec)); |
| 1153 | TF_RETURN_IF_ERROR(c->Merge(channel_dim, c->Dim(vec, 0), &channel_dim)); |
| 1154 | } |
| 1155 | |
| 1156 | ShapeHandle y; |
| 1157 | TF_RETURN_IF_ERROR(c->ReplaceDim(x, channel_dim_index, channel_dim, &y)); |
| 1158 | c->set_output(0, y); |
| 1159 | ShapeHandle vector_shape = c->Vector(channel_dim); |
| 1160 | c->set_output(1, vector_shape); |
| 1161 | c->set_output(2, vector_shape); |
| 1162 | c->set_output(3, vector_shape); |
| 1163 | c->set_output(4, vector_shape); |
| 1164 | return Status::OK(); |
| 1165 | } |
| 1166 | |
| 1167 | Status FusedBatchNormV3Shape(shape_inference::InferenceContext* c) { |
| 1168 | TF_RETURN_IF_ERROR(FusedBatchNormShape(c)); |
no test coverage detected