aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWon Jeon <won.jeon@arm.com>2024-01-18 06:31:55 +0000
committerWon Jeon <won.jeon@arm.com>2024-01-23 16:56:33 +0000
commit64e4bfe627ded0ba44ff60b23db28c1ff5d73d13 (patch)
treee4744f2124d90882c97af2159c460ba1d7c46d86
parent8690a0873fac28acccbb0acb15c16e8337e14df1 (diff)
downloadreference_model-64e4bfe627ded0ba44ff60b23db28c1ff5d73d13.tar.gz
Update RESHAPE and TILE conformance testing
Signed-off-by: Won Jeon <won.jeon@arm.com> Change-Id: Iaf59472cb32e03a92bad87ae9dba1b7548f20268
-rw-r--r--reference_model/CMakeLists.txt2
-rw-r--r--reference_model/src/generate/generate_entry.cc7
-rw-r--r--reference_model/src/generate/generate_fixed_data.cc56
-rw-r--r--reference_model/src/generate/generate_fixed_data.h34
-rw-r--r--reference_model/src/generate/generate_utils.cc15
-rw-r--r--reference_model/src/generate/generate_utils.h12
-rw-r--r--scripts/schemavalidation/datagen-config.schema.json19
-rw-r--r--verif/generator/datagenerator.py2
-rw-r--r--verif/generator/tosa_arg_gen.py79
-rw-r--r--verif/generator/tosa_test_gen.py30
-rw-r--r--verif/generator/tosa_utils.py5
11 files changed, 213 insertions, 48 deletions
diff --git a/reference_model/CMakeLists.txt b/reference_model/CMakeLists.txt
index 178594b..d2dce3c 100644
--- a/reference_model/CMakeLists.txt
+++ b/reference_model/CMakeLists.txt
@@ -73,6 +73,7 @@ set(CXX_SOURCE
src/generate/generate_dot_product_states.cc
src/generate/generate_dot_product.cc
src/generate/generate_pseudo_random.cc
+ src/generate/generate_fixed_data.cc
src/generate/generate_entry.cc
src/generate/generate_utils.cc
src/verify/verify_abs_error.cc
@@ -173,6 +174,7 @@ add_library(tosa_reference_generate_lib SHARED
src/generate/generate_dot_product_states.cc
src/generate/generate_dot_product.cc
src/generate/generate_pseudo_random.cc
+ src/generate/generate_fixed_data.cc
src/generate/generate_entry.cc
src/generate/generate_utils.cc
src/generate/generate_config.cc
diff --git a/reference_model/src/generate/generate_entry.cc b/reference_model/src/generate/generate_entry.cc
index 741cd79..91b2fc7 100644
--- a/reference_model/src/generate/generate_entry.cc
+++ b/reference_model/src/generate/generate_entry.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2023, ARM Limited.
+// Copyright (c) 2023-2024, ARM Limited.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
#include "generate.h"
#include "generate_dot_product.h"
+#include "generate_fixed_data.h"
#include "generate_pseudo_random.h"
#include "generate_utils.h"
@@ -36,6 +37,10 @@ bool generate(const GenerateConfig& cfg, void* data, size_t size)
return generatePseudoRandom(cfg, data, size);
break;
}
+ case GeneratorType::FixedData: {
+ return generateFixedData(cfg, data, size);
+ break;
+ }
default: {
WARNING("[Generator] Unsupported generation mode.");
break;
diff --git a/reference_model/src/generate/generate_fixed_data.cc b/reference_model/src/generate/generate_fixed_data.cc
new file mode 100644
index 0000000..d83ee58
--- /dev/null
+++ b/reference_model/src/generate/generate_fixed_data.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2024, ARM Limited.
+//
+// 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.
+#include "generate.h"
+#include "generate_utils.h"
+
+#include <algorithm>
+#include <array>
+#include <iterator>
+#include <type_traits>
+#include <vector>
+
+namespace TosaReference
+{
+bool generateFixedData(const GenerateConfig& cfg, void* data, size_t size)
+{
+ // Check we support the operator
+ if (cfg.opType == Op::Op_UNKNOWN)
+ {
+ WARNING("[Generator][FD] Unknown operator.");
+ return false;
+ }
+
+ switch (cfg.dataType)
+ {
+ case DType::DType_SHAPE: {
+ int32_t* outData = reinterpret_cast<int32_t*>(data);
+ std::vector<int32_t> inData = cfg.fixedDataInfo.data;
+ const auto T = TosaReference::numElementsFromShape(cfg.shape);
+ if (T != inData.size())
+ {
+ WARNING("[Generator][FD] Size does not match.");
+ return false;
+ }
+ for (auto t = 0; t < T; t++)
+ {
+ outData[t] = inData[t];
+ }
+ return true;
+ }
+ default:
+ WARNING("[Generator][FD] Unsupported type.");
+ return false;
+ }
+}
+} // namespace TosaReference
diff --git a/reference_model/src/generate/generate_fixed_data.h b/reference_model/src/generate/generate_fixed_data.h
new file mode 100644
index 0000000..50371c8
--- /dev/null
+++ b/reference_model/src/generate/generate_fixed_data.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2024, ARM Limited.
+//
+// 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 GENERATE_FIXED_DATA_H_
+#define GENERATE_FIXED_DATA_H_
+
+#include "generate_utils.h"
+
+namespace TosaReference
+{
+
+/// \brief Perform fixed data generation
+///
+/// \param cfg Generator related meta-data
+/// \param data Buffer to generate the data to
+/// \param size Size of the buffer
+///
+/// \return True on successful generation
+bool generateFixedData(const GenerateConfig& cfg, void* data, size_t size);
+
+}; // namespace TosaReference
+
+#endif // GENERATE_FIXED_DATA_H_
diff --git a/reference_model/src/generate/generate_utils.cc b/reference_model/src/generate/generate_utils.cc
index c16d1c6..9eda0b6 100644
--- a/reference_model/src/generate/generate_utils.cc
+++ b/reference_model/src/generate/generate_utils.cc
@@ -33,6 +33,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(DType,
{ DType::DType_FP16, "FP16" },
{ DType::DType_BF16, "BF16" },
{ DType::DType_FP32, "FP32" },
+ { DType::DType_SHAPE, "SHAPE" },
})
NLOHMANN_JSON_SERIALIZE_ENUM(Op,
@@ -93,6 +94,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(GeneratorType,
{ GeneratorType::OpFullRange, "OP_FULL_RANGE" },
{ GeneratorType::OpBoundary, "OP_BOUNDARY" },
{ GeneratorType::OpSpecial, "OP_SPECIAL" },
+ { GeneratorType::FixedData, "FIXED_DATA" },
})
// NOTE: This assumes it's VARIABLE if the InputType is not recognized
@@ -130,6 +132,11 @@ void from_json(const nlohmann::json& j, PseudoRandomInfo& pseudoRandomInfo)
}
}
+void from_json(const nlohmann::json& j, FixedDataInfo& fixedDataInfo)
+{
+ j.at("data").get_to(fixedDataInfo.data);
+}
+
void from_json(const nlohmann::json& j, GenerateConfig& cfg)
{
j.at("data_type").get_to(cfg.dataType);
@@ -158,6 +165,13 @@ void from_json(const nlohmann::json& j, GenerateConfig& cfg)
{
j.at("pseudo_random_info").get_to(cfg.pseudoRandomInfo);
}
+
+ // Set up defaults for fixedDataInfo
+ cfg.fixedDataInfo.data = std::vector<int32_t>();
+ if (j.contains("fixed_data_info"))
+ {
+ j.at("fixed_data_info").get_to(cfg.fixedDataInfo);
+ }
}
std::optional<GenerateConfig> parseGenerateConfig(const char* json, const char* tensorName)
@@ -209,6 +223,7 @@ size_t elementSizeFromType(DType type)
return 2;
case DType::DType_INT32:
case DType::DType_FP32:
+ case DType::DType_SHAPE:
return 4;
default:
return 0;
diff --git a/reference_model/src/generate/generate_utils.h b/reference_model/src/generate/generate_utils.h
index f9ec713..697b404 100644
--- a/reference_model/src/generate/generate_utils.h
+++ b/reference_model/src/generate/generate_utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2023, ARM Limited.
+// Copyright (c) 2023-2024, ARM Limited.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ enum class GeneratorType
OpFullRange,
OpBoundary,
OpSpecial,
+ FixedData,
};
/// \brief Supported input types
@@ -65,6 +66,14 @@ struct PseudoRandomInfo
bool round;
};
+/// \brief Fixed data generator meta-data
+struct FixedDataInfo
+{
+ FixedDataInfo() = default;
+
+ std::vector<int32_t> data;
+};
+
/// \brief Generator configuration
struct GenerateConfig
{
@@ -76,6 +85,7 @@ struct GenerateConfig
tosa::Op opType;
DotProductInfo dotProductInfo;
PseudoRandomInfo pseudoRandomInfo;
+ FixedDataInfo fixedDataInfo;
};
/// \brief Parse the generator config when given in JSON form
diff --git a/scripts/schemavalidation/datagen-config.schema.json b/scripts/schemavalidation/datagen-config.schema.json
index 08d564b..a74d79f 100644
--- a/scripts/schemavalidation/datagen-config.schema.json
+++ b/scripts/schemavalidation/datagen-config.schema.json
@@ -1,5 +1,5 @@
{
- "$comment": "Copyright (c) 2023, ARM Limited.",
+ "$comment": "Copyright (c) 2023-2024, ARM Limited.",
"$comment": "SPDX-License-Identifier: Apache-2.0",
"$id": "datagen-config.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -147,6 +147,23 @@
},
"additionalProperties": false,
"required": [ "sub_generator" ]
+ },
+ "fixed_data_info": {
+ "description": "info required for FIXED_DATA generator",
+ "type": "object",
+ "properties":
+ {
+ "data": {
+ "description": "flattened fixed data",
+ "type": "array",
+ "items": {
+ "description": "integer tensor data",
+ "type": "integer"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [ "data" ]
}
},
"additionalProperties": false,
diff --git a/verif/generator/datagenerator.py b/verif/generator/datagenerator.py
index b5ef35d..743475c 100644
--- a/verif/generator/datagenerator.py
+++ b/verif/generator/datagenerator.py
@@ -78,7 +78,7 @@ class GenerateLibrary:
size_bytes = size * 2
# Create buffer of bytes and initialize to zero
buffer = (ct.c_ubyte * size_bytes)(0)
- elif dtype == "INT32":
+ elif dtype == "INT32" or dtype == "SHAPE":
# Create buffer and initialize to zero
buffer = (ct.c_int32 * size)(0)
size_bytes = size * 4
diff --git a/verif/generator/tosa_arg_gen.py b/verif/generator/tosa_arg_gen.py
index 00490fa..a655a50 100644
--- a/verif/generator/tosa_arg_gen.py
+++ b/verif/generator/tosa_arg_gen.py
@@ -731,7 +731,11 @@ class TosaTensorValuesGen:
# Change from inclusive to exclusive range
data_range = (data_range[0], data_range[1] + 1)
# Ignore lazy data gen option and create data array using any range limits
- arr = testGen.getRandTensor(shape, dtype, data_range)
+
+ if "fixed_data" in argsDict and argsDict["fixed_data"][idx] is not None:
+ arr = np.int64(argsDict["fixed_data"][idx])
+ else:
+ arr = testGen.getRandTensor(shape, dtype, data_range)
if roundMode:
arr = np.round(arr)
if idx < pCount:
@@ -751,7 +755,13 @@ class TosaTensorValuesGen:
for idx, shape in enumerate(shapeList):
tens_meta = {}
- tens_meta["generator"] = gtu.DataGenType(dg_type).name
+ if "fixed_data" in argsDict and argsDict["fixed_data"][idx] is not None:
+ tens_meta["generator"] = gtu.DataGenType(
+ gtu.DataGenType.FIXED_DATA
+ ).name
+ else:
+ tens_meta["generator"] = gtu.DataGenType(dg_type).name
+
tens_meta["data_type"] = gtu.DTYPE_ATTRIBUTES[dtypeList[idx]]["json"]
tens_meta["shape"] = [int(i) for i in shape]
tens_meta["input_pos"] = idx
@@ -764,23 +774,30 @@ class TosaTensorValuesGen:
if dg_type == gtu.DataGenType.PSEUDO_RANDOM:
info = {}
- # TODO - generate seed for this generator based on test
- info["rng_seed"] = 42
-
- data_range = None
- if "data_range_list" in argsDict:
- data_range = argsDict["data_range_list"][idx]["range"]
- if "round" in argsDict["data_range_list"][idx]:
- info["round"] = argsDict["data_range_list"][idx]["round"]
- elif "data_range" in argsDict:
- data_range = argsDict["data_range"]
-
- if data_range is None:
- data_range = testGen.getDTypeRange(
- dtypeList[idx], high_inclusive=True
- )
- info["range"] = [str(v) for v in data_range]
- tens_meta["pseudo_random_info"] = info
+ if (
+ tens_meta["generator"]
+ == gtu.DataGenType(gtu.DataGenType.FIXED_DATA).name
+ ):
+ info["data"] = [int(i) for i in argsDict["fixed_data"][idx]]
+ tens_meta["fixed_data_info"] = info
+ else:
+ # TODO - generate seed for this generator based on test
+ info["rng_seed"] = 42
+
+ data_range = None
+ if "data_range_list" in argsDict:
+ data_range = argsDict["data_range_list"][idx]["range"]
+ if "round" in argsDict["data_range_list"][idx]:
+ info["round"] = argsDict["data_range_list"][idx]["round"]
+ elif "data_range" in argsDict:
+ data_range = argsDict["data_range"]
+
+ if data_range is None:
+ data_range = testGen.getDTypeRange(
+ dtypeList[idx], high_inclusive=True
+ )
+ info["range"] = [str(v) for v in data_range]
+ tens_meta["pseudo_random_info"] = info
elif dg_type == gtu.DataGenType.DOT_PRODUCT:
info = {}
info["s"] = argsDict["s"]
@@ -812,6 +829,9 @@ class TosaTensorValuesGen:
dg_tens_meta[temp_name] = tens_meta
# Create data now using the temporary name to access meta details
data = testGen.dgl.get_tensor_data(temp_name, tens_data)
+ if tens_meta["data_type"] == "SHAPE":
+ # Tensor type SHAPE and Numpy file type must be the same
+ data = np.int64(data)
# Remove the item as we will give it the correct name later
del dg_tens_meta[temp_name]
@@ -1014,6 +1034,27 @@ class TosaTensorValuesGen:
return placeholders
@staticmethod
+ def tvgReshape(testGen, op, dtypeList, shapeList, argsDict, error_name=None):
+ dtypeList[1] = DType.SHAPE
+ shapeList[1] = [len(argsDict["new_shape"])]
+ # Create a new list for the pre-generated data in argsDict["fixed_data"]
+ argsDict["fixed_data"] = [None, argsDict["new_shape"]]
+
+ return TosaTensorValuesGen.tvgLazyGenDefault(
+ testGen, op, dtypeList, shapeList, argsDict, error_name
+ )
+
+ @staticmethod
+ def tvgTile(testGen, op, dtypeList, shapeList, argsDict, error_name=None):
+ dtypeList[1] = DType.SHAPE
+ shapeList[1] = [len(argsDict["multiples"])]
+ argsDict["fixed_data"] = [None, argsDict["multiples"]]
+
+ return TosaTensorValuesGen.tvgLazyGenDefault(
+ testGen, op, dtypeList, shapeList, argsDict, error_name
+ )
+
+ @staticmethod
def tvgSelect(testGen, opName, dtypeList, shapeList, argsDict, error_name=None):
# Set datatype of condition tensor to boolean
dtypeList[0] = DType.BOOL
diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py
index 67ac367..159ee83 100644
--- a/verif/generator/tosa_test_gen.py
+++ b/verif/generator/tosa_test_gen.py
@@ -1558,22 +1558,14 @@ class TosaTestGen:
):
assert len(inputs) == 2
a = inputs[0]
- # second input is not properly generated yet
- # new_shape = inputs[1]
-
- # modify inputs[1] by a shape tensor from new_shape arg value
- new_shape_attr = args_dict["new_shape"]
- shape_array = np.array(new_shape_attr)
- shape = shape_array.shape
- new_shape = self.ser.addPlaceholder(shape, DType.SHAPE, shape_array)
- inputs[1] = new_shape
-
+ shape = inputs[1]
+ shape_attr = args_dict["new_shape"]
result_tensor = OutputShaper.reshapeOp(
- self.ser, self.rng, a, new_shape_attr, error_name
+ self.ser, self.rng, a, shape_attr, error_name
)
# Invalidate Input/Output list for error if checks.
- input_list = [a.name, new_shape.name]
+ input_list = [a.name, shape.name]
output_list = [result_tensor.name]
pCount, cCount = op["operands"]
num_operands = pCount + cCount
@@ -1725,16 +1717,8 @@ class TosaTestGen:
):
assert len(inputs) == 2
a = inputs[0]
- # second input is not properly generated yet
- # multiples = inputs[1]
-
- # modify inputs[1] by a shape tensor from multiples arg value
+ multiples = inputs[1]
multiples_attr = args_dict["multiples"]
- shape_array = np.int64(np.array(multiples_attr))
- shape = shape_array.shape
- multiples = self.ser.addPlaceholder(shape, DType.SHAPE, shape_array)
- inputs[1] = multiples
-
result_tensor = OutputShaper.tileOp(
self.ser, self.rng, a, multiples_attr, error_name
)
@@ -4236,7 +4220,7 @@ class TosaTestGen:
"build_fcn": (
build_reshape,
TosaTensorGen.tgBasic,
- TosaTensorValuesGen.tvgLazyGenDefault,
+ TosaTensorValuesGen.tvgReshape,
TosaArgGen.agReshape,
),
"types": TYPE_FIB,
@@ -4302,7 +4286,7 @@ class TosaTestGen:
"build_fcn": (
build_tile,
TosaTensorGen.tgBasic,
- TosaTensorValuesGen.tvgLazyGenDefault,
+ TosaTensorValuesGen.tvgTile,
TosaArgGen.agTile,
),
"types": TYPE_FIB,
diff --git a/verif/generator/tosa_utils.py b/verif/generator/tosa_utils.py
index 3d733f4..33db95f 100644
--- a/verif/generator/tosa_utils.py
+++ b/verif/generator/tosa_utils.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2023, ARM Limited.
+# Copyright (c) 2021-2024, ARM Limited.
# SPDX-License-Identifier: Apache-2.0
import struct
import sys
@@ -49,13 +49,14 @@ class DataGenType(IntEnum):
OP_BOUNDARY = 2
OP_FULLSET = 3
OP_SPECIAL = 4
+ FIXED_DATA = 5
def dtypeIsSupportedByCompliance(dtype):
"""Types supported by the new data generation and compliance flow."""
if isinstance(dtype, list) or isinstance(dtype, tuple):
dtype = dtype[0]
- return dtype in (DType.FP32, DType.FP16)
+ return dtype in (DType.FP32, DType.FP16, DType.SHAPE)
def getOpNameFromOpListName(opName):