[WebNN EP] Support Gelu op (#20240)

This commit is contained in:
Wanming Lin 2024-04-12 10:55:44 +08:00 committed by GitHub
parent 12042a9387
commit 667d2eb8e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 0 deletions

View file

@ -179,6 +179,7 @@ static const InlinedHashMap<std::string, WebnnOpInfo> op_map = {
{"Flatten", {"reshape", true}},
{"Floor", {"floor", true}},
{"Gather", {"gather", false}},
{"Gelu", {"gelu", false}},
{"Gemm", {"gemm", true}},
{"GlobalAveragePool", {"averagePool2d", true}},
{"GlobalMaxPool", {"maxPool2d", true}},

View file

@ -17,6 +17,10 @@ class ActivationOpBuilder : public BaseOpBuilder {
private:
Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node,
const logging::Logger& logger) const override ORT_MUST_USE_RESULT;
// Operator support related.
bool IsOpSupportedImpl(const InitializedTensorSet& initializers, const Node& node,
WebnnDeviceType /* device_type */, const logging::Logger& logger) const override;
};
// Add operator related.
@ -37,6 +41,8 @@ Status ActivationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
if (op_type == "Elu") {
options.set("alpha", helper.Get("alpha", 1.0f));
output = model_builder.GetBuilder().call<emscripten::val>("elu", input, options);
} else if (op_type == "Gelu") {
output = model_builder.GetBuilder().call<emscripten::val>("gelu", input, options);
} else if (op_type == "HardSigmoid") {
options.set("alpha", helper.Get("alpha", 0.2f));
options.set("beta", helper.Get("beta", 0.5f));
@ -66,6 +72,20 @@ Status ActivationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
return Status::OK();
}
// Operator support related.
bool ActivationOpBuilder::IsOpSupportedImpl(const InitializedTensorSet& /* initializers */,
const Node& node,
WebnnDeviceType /* device_type */,
const logging::Logger& logger) const {
const auto& input_defs = node.InputDefs();
std::vector<int64_t> input_shape;
if (!GetShape(*input_defs[0], input_shape, logger))
return false;
return true;
}
void CreateActivationOpBuilder(const std::string& op_type, OpBuilderRegistrations& op_registrations) {
if (op_registrations.op_builder_map.count(op_type) > 0)
return;
@ -73,6 +93,7 @@ void CreateActivationOpBuilder(const std::string& op_type, OpBuilderRegistration
static std::vector<std::string> op_types =
{
"Elu",
"Gelu",
"HardSigmoid",
"HardSwish",
"LeakyRelu",

View file

@ -99,6 +99,8 @@ void ModelBuilder::PreprocessActivations() {
emscripten::val options = emscripten::val::object();
options.set("alpha", helper.Get("alpha", 1.0f));
activation_nodes_.emplace(node->Index(), wnn_builder_.call<emscripten::val>("elu", options));
} else if (op_type == "Gelu") {
activation_nodes_.emplace(node->Index(), wnn_builder_.call<emscripten::val>("gelu"));
} else if (op_type == "HardSigmoid") {
NodeAttrHelper helper(*node);
emscripten::val options = emscripten::val::object();

View file

@ -47,6 +47,7 @@ static OpBuilderRegistrations CreateOpBuilderRegistrations() {
{ // Activations
CreateActivationOpBuilder("Elu", op_registrations);
CreateActivationOpBuilder("Gelu", op_registrations);
CreateActivationOpBuilder("HardSigmoid", op_registrations);
CreateActivationOpBuilder("HardSwish", op_registrations);
CreateActivationOpBuilder("LeakyRelu", op_registrations);