aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWon Jeon <won.jeon@arm.com>2023-06-10 00:20:04 +0000
committerEric Kunze <eric.kunze@arm.com>2023-06-29 15:47:40 +0000
commit78155c63024c33d31e3b66e8e198fd5f93837df1 (patch)
treefcc16affd189eea6d1f4647d8fb4f6ea71a39ff2
parenteb74106e1bc52127e5631736e10e8f8b0b7a1d07 (diff)
downloadreference_model-78155c63024c33d31e3b66e8e198fd5f93837df1.tar.gz
Add support for ERF operator to reference model
Signed-off-by: Won Jeon <won.jeon@arm.com> Change-Id: Ib42b867287b83a183a0d0fb1f1eb29974f58fae4
-rw-r--r--reference_model/include/operators.h4
-rw-r--r--reference_model/src/operators.cc33
-rw-r--r--reference_model/src/ops/activation_funcs.cc29
-rw-r--r--reference_model/src/ops/activation_funcs.h14
-rw-r--r--reference_model/src/ops/op_factory.cc6
m---------thirdparty/serialization_lib0
-rw-r--r--verif/conformance/test_select.py6
-rw-r--r--verif/conformance/tosa_base_profile_framework_ops_info.json13
-rw-r--r--verif/conformance/tosa_main_profile_ops_info.json65
-rw-r--r--verif/frameworks/test_builder.py9
-rwxr-xr-xverif/frameworks/tosa_verif_framework_generator.py7
-rw-r--r--verif/generator/tosa_test_gen.py48
12 files changed, 230 insertions, 4 deletions
diff --git a/reference_model/include/operators.h b/reference_model/include/operators.h
index 6efb655..b12604f 100644
--- a/reference_model/include/operators.h
+++ b/reference_model/include/operators.h
@@ -1,5 +1,5 @@
-// Copyright (c) 2022, ARM Limited.
+// Copyright (c) 2022-2023, ARM Limited.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -150,6 +150,8 @@ extern "C"
tosa_status_t tosa_run_tanh(tosa_tensor_t client_input, tosa_tensor_t client_output);
+ tosa_status_t tosa_run_erf(tosa_tensor_t client_input, tosa_tensor_t client_output);
+
tosa_status_t tosa_run_add(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output);
tosa_status_t tosa_run_arithmetic_right_shift(tosa_tensor_t client_input1,
diff --git a/reference_model/src/operators.cc b/reference_model/src/operators.cc
index a0b5013..5796129 100644
--- a/reference_model/src/operators.cc
+++ b/reference_model/src/operators.cc
@@ -580,6 +580,37 @@ extern "C"
return tosa_status_valid;
}
+ tosa_status_t tosa_run_erf(tosa_tensor_t client_input, tosa_tensor_t client_output)
+ {
+ // Create operator attributes
+ TosaNoneAttribute attr;
+
+ // Create tensors
+ tosa::TosaSerializationTensor* input = translate_client_tensor(client_input, "input");
+ tosa::TosaSerializationTensor* output = translate_client_tensor(client_output, "output");
+
+ // Create operator
+ auto op = new tosa::TosaSerializationOperator(tosa::Op::Op_ERF, tosa::Attribute::Attribute_NONE, &attr,
+ { input->GetName() }, { output->GetName() });
+
+ // Create a tosa single-op basic block
+ tosa::TosaSerializationBasicBlock block("erf", "main", { op }, { input, output }, { input->GetName() },
+ { output->GetName() });
+
+ // Setup model
+ TosaReference::ModelRunnerImpl runner;
+ TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.initialize(block));
+ TOSA_RETURN_ON_ERROR(runner.setInput(input->GetName(), client_input.data, client_input.size));
+
+ // Execute
+ TOSA_RETURN_ON_GRAPH_STATUS_ERROR(runner.run());
+
+ // Extract outputs
+ TOSA_RETURN_ON_ERROR(runner.getOutput(output->GetName(), client_output.data, client_output.size));
+
+ return tosa_status_valid;
+ }
+
tosa_status_t tosa_run_add(tosa_tensor_t client_input1, tosa_tensor_t client_input2, tosa_tensor_t client_output)
{
// Create operator attributes
@@ -2324,4 +2355,4 @@ extern "C"
return tosa_status_valid;
}
-} // extern "C" \ No newline at end of file
+} // extern "C"
diff --git a/reference_model/src/ops/activation_funcs.cc b/reference_model/src/ops/activation_funcs.cc
index 6681d6d..12d0697 100644
--- a/reference_model/src/ops/activation_funcs.cc
+++ b/reference_model/src/ops/activation_funcs.cc
@@ -124,6 +124,30 @@ int OpTanh<Rank, Dtype>::register_fcn()
return 0;
}
+template <int Rank, TOSA_REF_TYPE Dtype>
+int OpErf<Rank, Dtype>::register_fcn()
+{
+ // Check Tosa Level
+ auto tosa_level = g_func_config.tosa_level;
+ LEVEL_CHECK(Rank <= tosa_level.MAX_RANK, "Rank should be similar than or equal to MAX_RANK");
+
+ switch (Dtype)
+ {
+ case TOSA_REF_TYPE_FP16:
+ case TOSA_REF_TYPE_BF16:
+ case TOSA_REF_TYPE_FP32:
+ this->fcn = [](InEigenType a) -> OutEigenType { return fpTrunc<Dtype>(erff(a)); };
+ break;
+ case TOSA_REF_TYPE_FP64:
+ this->fcn = [](InEigenType a) -> OutEigenType { return erf(a); };
+ break;
+ default:
+ ERROR_IF(true, "unsupported TOSA_REF_TYPE %s", EnumNameTOSAREFTYPE(Dtype));
+ }
+
+ return 0;
+}
+
// template explicit instantiation
DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpClamp, FP16);
DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpClamp, BF16);
@@ -141,3 +165,8 @@ DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, BF16);
DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, FP16);
DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, FP32);
DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, FP64);
+
+DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, BF16);
+DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP16);
+DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP32);
+DEF_INSTANTIATE_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP64);
diff --git a/reference_model/src/ops/activation_funcs.h b/reference_model/src/ops/activation_funcs.h
index 2372fcb..a7e1275 100644
--- a/reference_model/src/ops/activation_funcs.h
+++ b/reference_model/src/ops/activation_funcs.h
@@ -77,6 +77,20 @@ public:
virtual int register_fcn();
};
+template <int Rank, TOSA_REF_TYPE Dtype>
+class OpErf : public UnaryNode<Rank, Dtype>
+{
+public:
+ OpErf(SubgraphTraverser* sgt_, TosaAttributeBase* attribute_, uint64_t id_)
+ : UnaryNode<Rank, Dtype>(sgt_, Op_ERF, id_)
+ {
+ register_fcn();
+ }
+ using InEigenType = typename GetEigenType<Dtype>::type;
+ using OutEigenType = typename GetEigenType<Dtype>::type;
+ virtual int register_fcn();
+};
+
}; // namespace TosaReference
#endif
diff --git a/reference_model/src/ops/op_factory.cc b/reference_model/src/ops/op_factory.cc
index 0a78884..a3069dc 100644
--- a/reference_model/src/ops/op_factory.cc
+++ b/reference_model/src/ops/op_factory.cc
@@ -161,6 +161,12 @@ GraphNode* OpFactory::newOp(SubgraphTraverser* sgt,
DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, FP32);
DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpTanh, FP64);
break;
+ case Op_ERF:
+ DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP16);
+ DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, BF16);
+ DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP32);
+ DEF_FACTORY_RANK0_6_ONE_RANK_ONE_TYPE(OpErf, FP64);
+ break;
// ewise_binary
case Op_ADD:
diff --git a/thirdparty/serialization_lib b/thirdparty/serialization_lib
-Subproject 8a2704330c18532d79a65ad2733458a80bf9c5b
+Subproject 3acb1cbfdd492ab4f657799ed0c2279a5e39024
diff --git a/verif/conformance/test_select.py b/verif/conformance/test_select.py
index 9868a7f..f4e2a61 100644
--- a/verif/conformance/test_select.py
+++ b/verif/conformance/test_select.py
@@ -518,6 +518,12 @@ class ExpOperator(Operator):
name = "exp"
+class ErfOperator(Operator):
+ """Test selector for the ERF operator."""
+
+ name = "erf"
+
+
class FFT2DOperator(Operator):
"""Test selector for the FFT2D operator."""
diff --git a/verif/conformance/tosa_base_profile_framework_ops_info.json b/verif/conformance/tosa_base_profile_framework_ops_info.json
index 24a23b5..5d7e4a3 100644
--- a/verif/conformance/tosa_base_profile_framework_ops_info.json
+++ b/verif/conformance/tosa_base_profile_framework_ops_info.json
@@ -85,6 +85,16 @@
"tosa-mi"
]
},
+ "erf": {
+ "tests": [
+ "erf_13x21x3_qu8",
+ "erf_14x19_qi8",
+ "erf_1x8x4x17_qi16"
+ ],
+ "profile": [
+ "tosa-mi"
+ ]
+ },
"fully_connected": {
"alternate_names": [
"matmul"
@@ -257,8 +267,7 @@
"tanh_1x8x4x17_qi16"
],
"profile": [
- "tosa-bi",
"tosa-mi"
]
}
-} \ No newline at end of file
+}
diff --git a/verif/conformance/tosa_main_profile_ops_info.json b/verif/conformance/tosa_main_profile_ops_info.json
index 5df89d6..07b6af3 100644
--- a/verif/conformance/tosa_main_profile_ops_info.json
+++ b/verif/conformance/tosa_main_profile_ops_info.json
@@ -2925,5 +2925,70 @@
]
}
}
+ },
+ "erf": {
+ "group": "activation",
+ "profile": [
+ "tosa-mi"
+ ],
+ "generation": {
+ "standard": {
+ "generator_args": [
+ [
+ "--target-dtype",
+ "fp32",
+ "--target-dtype",
+ "fp16",
+ "--target-dtype",
+ "bf16",
+ "--fp-values-range",
+ "-2.0,2.0",
+ "--tensor-dim-range",
+ "18,60",
+ "--target-rank",
+ "1",
+ "--target-rank",
+ "2",
+ "--target-rank",
+ "3"
+ ],
+ [
+ "--target-dtype",
+ "fp32",
+ "--target-dtype",
+ "fp16",
+ "--target-dtype",
+ "bf16",
+ "--fp-values-range",
+ "-2.0,2.0",
+ "--tensor-dim-range",
+ "1,24",
+ "--target-rank",
+ "4",
+ "--target-rank",
+ "5"
+ ],
+ [
+ "--target-dtype",
+ "fp32",
+ "--fp-values-range",
+ "-2.0,2.0",
+ "--target-shape",
+ "1,65535,2,1,1",
+ "--target-shape",
+ "1,65540,1,2"
+ ]
+ ]
+ }
+ },
+ "selection": {
+ "default": {
+ "params": {},
+ "permutes": [
+ "shape",
+ "type"
+ ]
+ }
+ }
}
} \ No newline at end of file
diff --git a/verif/frameworks/test_builder.py b/verif/frameworks/test_builder.py
index 1b681d2..fcd72a3 100644
--- a/verif/frameworks/test_builder.py
+++ b/verif/frameworks/test_builder.py
@@ -348,6 +348,15 @@ class TBuilder:
def eval(self, a):
return tf.math.tanh(a, name=self.result_name)
+ class Erf:
+ # tfl.ops cannot be generated right now.
+ # https://github.com/tensorflow/tensorflow/issues/60809
+ def __init__(self, name):
+ self.result_name = name
+
+ def eval(self, a):
+ return tf.math.erf(a, name=self.result_name)
+
class Sin:
def __init__(self, name):
self.result_name = name
diff --git a/verif/frameworks/tosa_verif_framework_generator.py b/verif/frameworks/tosa_verif_framework_generator.py
index ccbe742..02ab8aa 100755
--- a/verif/frameworks/tosa_verif_framework_generator.py
+++ b/verif/frameworks/tosa_verif_framework_generator.py
@@ -338,6 +338,13 @@ TF_OP_LIST = {
),
},
},
+ "erf": {
+ "operands": (1, 0),
+ "build_fcn": (TBuilder.Erf, TGen.tgBasic, ArgGen.agNone),
+ "types": {
+ "tf": TYPE_F,
+ },
+ },
"sin": {
"operands": (1, 0),
"build_fcn": (TBuilder.Sin, TGen.tgBasic, ArgGen.agNone),
diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py
index 66084b4..bd371eb 100644
--- a/verif/generator/tosa_test_gen.py
+++ b/verif/generator/tosa_test_gen.py
@@ -1177,6 +1177,37 @@ class TosaTestGen:
self.ser.addOperator(op["op"], input_list, output_list)
return result_tens
+ def build_erf(self, op, a, validator_fcns=None, error_name=None):
+ result_tens = OutputShaper.unaryOp(self.ser, self.rng, a, error_name)
+
+ # Invalidate Input/Output list for error if checks.
+ input_list = [a.name]
+ output_list = [result_tens.name]
+ pCount, cCount = op["operands"]
+ num_operands = pCount + cCount
+ input_list, output_list = TosaErrorIfArgGen.eiInvalidateInputOutputList(
+ self, error_name, input_list, output_list
+ )
+
+ if not TosaErrorValidator.evValidateErrorIfs(
+ self.ser,
+ validator_fcns,
+ error_name,
+ op=op,
+ input_shape=a.shape,
+ output_shape=result_tens.shape,
+ input_dtype=a.dtype,
+ output_dtype=result_tens.dtype,
+ result_tensors=[result_tens],
+ input_list=input_list,
+ output_list=output_list,
+ num_operands=num_operands,
+ ):
+ return None
+
+ self.ser.addOperator(op["op"], input_list, output_list)
+ return result_tens
+
def build_concat(self, op, *a, validator_fcns=None, error_name=None):
if error_name != ErrorIf.WrongInputType:
assert type(a[-1]) == int
@@ -2907,6 +2938,23 @@ class TosaTestGen:
TosaErrorValidator.evWrongOutputList,
),
},
+ "erf": {
+ "op": Op.ERF,
+ "operands": (1, 0),
+ "build_fcn": (
+ build_erf,
+ TosaTensorGen.tgBasic,
+ TosaTensorValuesGen.tvgDefault,
+ None,
+ ),
+ "types": TYPE_FP,
+ "error_if_validators": (
+ TosaErrorValidator.evWrongInputType,
+ TosaErrorValidator.evWrongOutputType,
+ TosaErrorValidator.evWrongInputList,
+ TosaErrorValidator.evWrongOutputList,
+ ),
+ },
# Elementwise Binary Operators
"add": {
"op": Op.ADD,