diff --git a/js/web/docs/webnn-operators.md b/js/web/docs/webnn-operators.md index 4c6dab84fa..508f85377a 100644 --- a/js/web/docs/webnn-operators.md +++ b/js/web/docs/webnn-operators.md @@ -59,7 +59,7 @@ operators and the supported opset domain/versions in **WebNN EP** by ONNX Runtim | Not | ai.onnx(7+) | logicalnot | ✓ | ✓ | | | Pad | ai.onnx(7-10, 11-12, 13-17, 18, 19-20, 21+) | pad | ✓ | ✓ | modes == 'wrap' is not supported | | Pow | ai.onnx(7-11, 12, 13-14, 15+) | pow | ✓ | ✓ | | -| PRelu | ai.onnx(7-8, 9-15, 16+) | prelu | ✓ | ✓ | WebNN CPU restricts slope to be a static value | +| PRelu | ai.onnx(7-8, 9-15, 16+) | prelu | ✓ | ✓ | WebNN CPU backend restricts the last dimension of input and slope to be same (Chromium issue: https://issues.chromium.org/issues/335517470) | | Reciprocal | ai.onnx(7-12, 13+) | reciprocal | ✗ | ✓ | | | ReduceL1 | ai.onnx(7-10, 11-12, 13-17, 18+) | reduceL1 | ✗ | ✓ | Input 'axes' if present should be a constant | | ReduceL2 | ai.onnx(7-10, 11-12, 13-17, 18+) | reduceL2 | ✗ | ✓ | Input 'axes' if present should be a constant | diff --git a/onnxruntime/core/providers/webnn/builders/impl/binary_op_builder.cc b/onnxruntime/core/providers/webnn/builders/impl/binary_op_builder.cc index 2c97ef490f..23e19d5943 100644 --- a/onnxruntime/core/providers/webnn/builders/impl/binary_op_builder.cc +++ b/onnxruntime/core/providers/webnn/builders/impl/binary_op_builder.cc @@ -63,14 +63,23 @@ bool BinaryOpBuilder::IsOpSupportedImpl(const InitializedTensorSet& initializers const auto& input_defs = node.InputDefs(); const auto& op_type = node.OpType(); - // XNNPACK prelu operator expects slope to be a static value. - // https://github.com/google/XNNPACK/issues/4692 - // TODO: Remove this check after it is solved. - if (op_type == "PRelu" && !Contains(initializers, input_defs[1]->Name()) && device_type == WebnnDeviceType::CPU) { - LOGS(logger, VERBOSE) << "The second input (slope) for PRelu must be a constant initializer for WebNN CPU backend."; + std::vector input0_shape; + std::vector input1_shape; + if (!GetShape(*input_defs[0], input0_shape, logger) || + !GetShape(*input_defs[1], input1_shape, logger)) { return false; } + // 'prelu' op in WebNN CPU backend restricts the last dimension of input and slope to be same. + // TODO: Remove this workaround once the associated issue is resolved in Chromium: + // https://issues.chromium.org/issues/335517470. + if (op_type == "PRelu" && device_type == WebnnDeviceType::CPU) { + if (input0_shape.back() != input1_shape.back()) { + LOGS(logger, VERBOSE) << "The last dimension of input and slope for PRelu must be same for WebNN CPU backend."; + return false; + } + } + return true; }