diff --git a/compiler/luci/lang/include/luci/IR/CircleNodes.h b/compiler/luci/lang/include/luci/IR/CircleNodes.h index 0cae7a8f205..3c4e378772d 100644 --- a/compiler/luci/lang/include/luci/IR/CircleNodes.h +++ b/compiler/luci/lang/include/luci/IR/CircleNodes.h @@ -146,6 +146,7 @@ // Virtual nodes #include "Nodes/CircleConst.h" #include "Nodes/CircleInput.h" +#include "Nodes/CircleLayerNorm.h" #include "Nodes/CircleOutput.h" #include "Nodes/CircleVariable.h" // Multi-output virtual nodes diff --git a/compiler/luci/lang/include/luci/IR/CircleNodes.lst b/compiler/luci/lang/include/luci/IR/CircleNodes.lst index 50ddfbcd7a9..c5c807ffe5e 100644 --- a/compiler/luci/lang/include/luci/IR/CircleNodes.lst +++ b/compiler/luci/lang/include/luci/IR/CircleNodes.lst @@ -144,6 +144,7 @@ CIRCLE_NODE(ROPE, CircleRoPE) // Virtual node(s) CIRCLE_VNODE(CIRCLECONST, CircleConst) CIRCLE_VNODE(CIRCLEINPUT, CircleInput) +CIRCLE_VNODE(CIRCLELAYERNORM, CircleLayerNorm) CIRCLE_VNODE(CIRCLEOUTPUT, CircleOutput) CIRCLE_VNODE(CIRCLEOUTPUTDUMMY, CircleOutputDummy) CIRCLE_VNODE(CIRCLEOUTPUTEXCLUDE, CircleOutputExclude) diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleLayerNorm.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleLayerNorm.h new file mode 100644 index 00000000000..ceea28d2aab --- /dev/null +++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleLayerNorm.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LUCI_IR_CIRCLE_LAYER_NORM_H__ +#define __LUCI_IR_CIRCLE_LAYER_NORM_H__ + +#include "luci/IR/CircleNodeDecl.h" +#include "luci/IR/CircleOpcode.h" + +#include "luci/IR/AttrFusedActFunc.h" +#include "luci/IR/CircleNodeMixins.h" + +namespace luci +{ + +/** + * @brief Virtual LayerNorm + */ +class CircleLayerNorm final + : public FixedArityNode<3, CircleNodeImpl> +{ +public: + loco::Node *input(void) const { return at(0)->node(); } + void input(loco::Node *node) { at(0)->node(node); } + + loco::Node *gamma(void) const { return at(1)->node(); } + void gamma(loco::Node *node) { at(1)->node(node); } + + loco::Node *beta(void) const { return at(2)->node(); } + void beta(loco::Node *node) { at(2)->node(node); } + +public: + float epsilon() const { return _epsilon; } + void epsilon(float epsilon) { _epsilon = epsilon; } + +private: + float _epsilon{1e-05}; +}; + +} // namespace luci + +#endif // __LUCI_IR_CIRCLE_LAYER_NORM_H__ diff --git a/res/TensorFlowLiteRecipes/Net_LayerNorm_000/test.recipe b/res/TensorFlowLiteRecipes/Net_LayerNorm_000/test.recipe new file mode 100644 index 00000000000..4377e60aad0 --- /dev/null +++ b/res/TensorFlowLiteRecipes/Net_LayerNorm_000/test.recipe @@ -0,0 +1,157 @@ +# +# Generated with tflchef-reverse +# refer https://github.com/Samsung/ONE/issues/14467 +# +operand { + name: "serving_default_input:0" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 4 + } +} +operand { + name: "onnx_tf_prefix_/ln/Constant_1" + type: FLOAT32 + shape { + } + filler { + tag: "explicit" + arg: "1e-05" + } +} +operand { + name: "onnx_tf_prefix_/ln/ReduceMean/reduction_indices" + type: INT32 + shape { + } + filler { + tag: "explicit" + arg: "-1" + } +} +operand { + name: "onnx_tf_prefix_/ln/ReduceMean" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 1 + } +} +operand { + name: "onnx_tf_prefix_/ln/Sub" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 4 + } +} +operand { + name: "onnx_tf_prefix_/ln/Pow;onnx_tf_prefix_/ln/Constant" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 4 + } +} +operand { + name: "onnx_tf_prefix_/ln/ReduceMean_1" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 1 + } +} +operand { + name: "onnx_tf_prefix_/ln/Add" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 1 + } +} +operand { + name: "onnx_tf_prefix_/ln/Div;onnx_tf_prefix_/ln/Sqrt" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 1 + } +} +operand { + name: "PartitionedCall:0" + type: FLOAT32 + shape { + dim: 1 + dim: 16 + dim: 4 + } +} +operation { + type: "Mean" + input: "serving_default_input:0" + input: "onnx_tf_prefix_/ln/ReduceMean/reduction_indices" + output: "onnx_tf_prefix_/ln/ReduceMean" + mean_options { + keep_dims: true + } +} +operation { + type: "Sub" + input: "serving_default_input:0" + input: "onnx_tf_prefix_/ln/ReduceMean" + output: "onnx_tf_prefix_/ln/Sub" + sub_options { + activation: NONE + } +} +operation { + type: "Mul" + input: "onnx_tf_prefix_/ln/Sub" + input: "onnx_tf_prefix_/ln/Sub" + output: "onnx_tf_prefix_/ln/Pow;onnx_tf_prefix_/ln/Constant" + mul_options { + activation: NONE + } +} +operation { + type: "Mean" + input: "onnx_tf_prefix_/ln/Pow;onnx_tf_prefix_/ln/Constant" + input: "onnx_tf_prefix_/ln/ReduceMean/reduction_indices" + output: "onnx_tf_prefix_/ln/ReduceMean_1" + mean_options { + keep_dims: true + } +} +operation { + type: "Add" + input: "onnx_tf_prefix_/ln/ReduceMean_1" + input: "onnx_tf_prefix_/ln/Constant_1" + output: "onnx_tf_prefix_/ln/Add" + add_options { + activation: NONE + } +} +operation { + type: "Rsqrt" + input: "onnx_tf_prefix_/ln/Add" + output: "onnx_tf_prefix_/ln/Div;onnx_tf_prefix_/ln/Sqrt" +} +operation { + type: "Mul" + input: "onnx_tf_prefix_/ln/Sub" + input: "onnx_tf_prefix_/ln/Div;onnx_tf_prefix_/ln/Sqrt" + output: "PartitionedCall:0" + mul_options { + activation: NONE + } +} +input: "serving_default_input:0" +output: "PartitionedCall:0"