| 492 | } |
| 493 | |
| 494 | TfLiteStatus PreluPrepare(TfLiteContext* context, TfLiteNode* node) { |
| 495 | TF_LITE_ENSURE_EQ(context, NumInputs(node), 2); |
| 496 | TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); |
| 497 | const TfLiteTensor* input = GetInput(context, node, 0); |
| 498 | TfLiteTensor* output = GetOutput(context, node, 0); |
| 499 | const TfLiteTensor* alpha = GetInput(context, node, 1); |
| 500 | PreluOpData* data = reinterpret_cast<PreluOpData*>(node->user_data); |
| 501 | |
| 502 | TF_LITE_ENSURE_EQ(context, input->type, alpha->type); |
| 503 | output->type = input->type; |
| 504 | |
| 505 | if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt16) { |
| 506 | double real_multiplier = |
| 507 | input->params.scale * alpha->params.scale / output->params.scale; |
| 508 | QuantizeMultiplierSmallerThanOneExp( |
| 509 | real_multiplier, &data->output_multiplier, &data->output_shift); |
| 510 | } |
| 511 | |
| 512 | // PRelu (parameteric Relu) shares the same alpha value on "shared axis". |
| 513 | // This means it's always required to "broadcast" alpha values in PRelu. |
| 514 | TfLiteIntArray* output_size = nullptr; |
| 515 | TF_LITE_ENSURE_OK( |
| 516 | context, CalculateShapeForBroadcast(context, input, alpha, &output_size)); |
| 517 | |
| 518 | TF_LITE_ENSURE_OK(context, |
| 519 | context->ResizeTensor(context, output, output_size)); |
| 520 | // After broadcasting, the output shape should always be the same as the |
| 521 | // input shape. |
| 522 | TF_LITE_ENSURE(context, HaveSameShapes(input, output)); |
| 523 | |
| 524 | return kTfLiteOk; |
| 525 | } |
| 526 | |
| 527 | TfLiteStatus ReluEval(TfLiteContext* context, TfLiteNode* node) { |
| 528 | const TfLiteTensor* input = GetInput(context, node, 0); |
nothing calls this directly
no test coverage detected