| 37 | explicit RequantizeOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} |
| 38 | |
| 39 | void Compute(OpKernelContext* ctx) override { |
| 40 | const Tensor& input = ctx->input(0); |
| 41 | const float input_min_float = ctx->input(1).flat<float>()(0); |
| 42 | const float input_max_float = ctx->input(2).flat<float>()(0); |
| 43 | const float requested_output_min_float = ctx->input(3).flat<float>()(0); |
| 44 | const float requested_output_max_float = ctx->input(4).flat<float>()(0); |
| 45 | |
| 46 | Tensor* output = nullptr; |
| 47 | OP_REQUIRES_OK(ctx, ctx->allocate_output(0, input.shape(), &output)); |
| 48 | Tensor* output_min = nullptr; |
| 49 | OP_REQUIRES_OK(ctx, ctx->allocate_output(1, TensorShape({}), &output_min)); |
| 50 | Tensor* output_max = nullptr; |
| 51 | OP_REQUIRES_OK(ctx, ctx->allocate_output(2, TensorShape({}), &output_max)); |
| 52 | |
| 53 | OP_REQUIRES( |
| 54 | ctx, requested_output_min_float <= 0.0f, |
| 55 | errors::InvalidArgument("requested_output_min must be <= 0, but got ", |
| 56 | requested_output_min_float)); |
| 57 | OP_REQUIRES( |
| 58 | ctx, requested_output_max_float >= requested_output_min_float, |
| 59 | errors::InvalidArgument( |
| 60 | "requested_output_max must be >= requested_output_min, but got ", |
| 61 | requested_output_max_float, " and ", requested_output_min_float)); |
| 62 | |
| 63 | auto input_array = input.flat<T1>(); |
| 64 | |
| 65 | #if 0 |
| 66 | // This is the reference, non-eigen implementation: |
| 67 | auto output_array = output->flat<T2>(); |
| 68 | RequantizeManyInNewRange<T1, T2>( |
| 69 | input_array.data(), input_array.size(), |
| 70 | input_min_float, input_max_float, |
| 71 | requested_output_min_float, requested_output_max_float, |
| 72 | output_array.data()); |
| 73 | #endif |
| 74 | |
| 75 | if (input_array.size() > 0) { |
| 76 | if (meta::IsSupportedAndEnabled() && std::is_same<T1, qint32>() && |
| 77 | std::is_same<T2, quint8>()) { |
| 78 | auto input_i32_array = input.flat<qint32>(); |
| 79 | meta::Requantize(ctx, input_i32_array.data(), input_i32_array.size(), |
| 80 | input_min_float, input_max_float, |
| 81 | requested_output_min_float, requested_output_max_float, |
| 82 | output->flat<quint8>().data()); |
| 83 | } else { |
| 84 | RequantizeManyInNewRangeUsingEigen<T1, T2>( |
| 85 | ctx->eigen_device<CPUDevice>(), input, input_min_float, |
| 86 | input_max_float, requested_output_min_float, |
| 87 | requested_output_max_float, output); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | output_min->flat<float>().setConstant(requested_output_min_float); |
| 92 | output_max->flat<float>().setConstant(requested_output_max_float); |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | REGISTER_KERNEL_BUILDER(Name("Requantize") |
nothing calls this directly
no test coverage detected