| 33 | namespace { |
| 34 | |
| 35 | Status FractionalPoolShapeFn(InferenceContext* c) { |
| 36 | ShapeHandle input; |
| 37 | TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 4, &input)); |
| 38 | |
| 39 | std::vector<float> pooling_ratio; |
| 40 | TF_RETURN_IF_ERROR(c->GetAttr("pooling_ratio", &pooling_ratio)); |
| 41 | if (pooling_ratio.size() != 4) { |
| 42 | return errors::InvalidArgument( |
| 43 | "pooling_ratio field must specify 4 dimensions"); |
| 44 | } |
| 45 | std::vector<DimensionHandle> output_dims; |
| 46 | for (int i = 0; i < 4; ++i) { |
| 47 | DimensionHandle d = c->Dim(input, i); |
| 48 | if (c->ValueKnown(d)) { |
| 49 | // This must match the same logic in the kernel function in |
| 50 | // core/kernels/fractional_max_pool_op.cc. |
| 51 | auto val = static_cast<int64>(std::floor(c->Value(d) / pooling_ratio[i])); |
| 52 | if (val < 0) { |
| 53 | return errors::InvalidArgument("Size computed for dim ", i, |
| 54 | " is negative: ", val); |
| 55 | } |
| 56 | output_dims.push_back(c->MakeDim(val)); |
| 57 | } else { |
| 58 | output_dims.push_back(c->UnknownDim()); |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | for (std::size_t i = 0; i < pooling_ratio.size(); ++i) { |
| 63 | if (pooling_ratio[i] < 1) { |
| 64 | return errors::InvalidArgument( |
| 65 | "pooling_ratio cannot be smaller than 1, got: ", pooling_ratio[i]); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | c->set_output(0, c->MakeShape(output_dims)); |
| 70 | c->set_output(1, c->Vector(output_dims[1])); |
| 71 | c->set_output(2, c->Vector(output_dims[2])); |
| 72 | return Status::OK(); |
| 73 | } |
| 74 | |
| 75 | } // namespace |
| 76 |
nothing calls this directly
no test coverage detected