aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Johnson <jeremy.johnson@arm.com>2023-12-13 14:28:12 +0000
committerEric Kunze <eric.kunze@arm.com>2023-12-14 17:56:59 +0000
commite1e611dc446fe597509b4b777bb474c059a1c0b6 (patch)
treefc9c229bafda83ac42a9d599b60be5fae3a7c619
parenta8420add949564053495ef78f3213f163c30fb9a (diff)
downloadreference_model-e1e611dc446fe597509b4b777bb474c059a1c0b6.tar.gz
Remove inferred dimension from RESHAPE
Test generation changed to only produce static reshape tests Reference model changed to produce ERROR_IF on inferred shapes Signed-off-by: Jeremy Johnson <jeremy.johnson@arm.com> Change-Id: I92c92a40e7c0e457961bc654630040dff79a750b
-rw-r--r--reference_model/src/ops/data_layout.cc48
-rw-r--r--verif/generator/tosa_arg_gen.py83
-rw-r--r--verif/generator/tosa_error_if.py50
-rw-r--r--verif/generator/tosa_test_gen.py2
4 files changed, 23 insertions, 160 deletions
diff --git a/reference_model/src/ops/data_layout.cc b/reference_model/src/ops/data_layout.cc
index 2d1fdb0..fa99d21 100644
--- a/reference_model/src/ops/data_layout.cc
+++ b/reference_model/src/ops/data_layout.cc
@@ -297,48 +297,11 @@ int OpReshape<InRank, OutRank, Dtype>::checkTensorAttributes()
return 1;
}
- // -1 shape inferencing
- auto inferred_size = -1;
- auto inferred_dim = -1;
- auto total_size = getInputs()[0]->getElementCount();
- uint32_t accum_size = 1;
-
+ // Check for unsupported -1 shape inferencing
for (int32_t d = 0; d < OutRank; d++)
{
- auto curr_new_shape = attribute->new_shape()[d];
- if (curr_new_shape != -1)
- {
- accum_size *= curr_new_shape;
- }
- else
- {
- ERROR_IF(inferred_dim != -1, "OpReshape: only 1 inferred dimension in output shape is supported");
- inferred_dim = d;
- }
- }
-
- ERROR_IF((total_size % accum_size) != 0,
- "OpReshape: shape inference failed, missing dimension would be non-integer");
- inferred_size = total_size / accum_size;
-
- if (inferred_dim != -1)
- {
- getOutputs()[0]->setDimSize(inferred_dim, inferred_size);
-
- // Need to also edit the serializedTensor's shape at inferred_dim
- TosaSerializationTensor* serializedTensor;
- for (auto region : parent_sgt->getTsh()->GetRegions())
- {
- for (auto block : region->GetBlocks())
- {
- if (block->GetTensorByName(getOutputs()[0]->getName()))
- {
- serializedTensor = block->GetTensorByName(getOutputs()[0]->getName());
- serializedTensor->SetDimSize(inferred_dim, inferred_size);
- break;
- }
- }
- }
+ auto curr_new_dim = attribute->new_shape()[d];
+ ERROR_IF(curr_new_dim == -1, "OpReshape: inferred dimensions in output shape are unsupported")
}
ERROR_IF(inputs[0]->getElementCount() != outputs[0]->getElementCount(),
@@ -346,9 +309,8 @@ int OpReshape<InRank, OutRank, Dtype>::checkTensorAttributes()
for (uint32_t d = 0; d < OutRank; d++)
{
- auto curr_new_shape = attribute->new_shape()[d];
- ERROR_IF(curr_new_shape != -1 && curr_new_shape != outputs[0]->getShape()[d],
- "OpReshape: new_shape doesn't match output shape");
+ auto curr_new_dim = attribute->new_shape()[d];
+ ERROR_IF(curr_new_dim != outputs[0]->getShape()[d], "OpReshape: new_shape doesn't match output shape");
}
in = dynamic_cast<TosaReference::TensorTemplate<TIn>*>(inputs[0]);
diff --git a/verif/generator/tosa_arg_gen.py b/verif/generator/tosa_arg_gen.py
index 50811ac..1e23822 100644
--- a/verif/generator/tosa_arg_gen.py
+++ b/verif/generator/tosa_arg_gen.py
@@ -2673,97 +2673,50 @@ class TosaArgGen:
arg_list = []
origShape = shapeList[0]
-
- totalElements = 1
- for s in origShape:
- totalElements *= s
-
- # This code is NOT fast. Fortunately, the numbers are fairly small.
+ totalElements = gtu.product(origShape)
factors = TosaArgGen.getFactors(totalElements)
+ # Find new shapes up to the number of permutations asked for
+ # This code is NOT fast. Fortunately, the numbers are fairly small.
for p in range(testGen.args.num_rand_permutations):
# Rank from 1 to TOSA_TENSOR_MAX_RANK
newRank = testGen.randInt(1, (testGen.TOSA_TENSOR_MAX_RANK + 1))
if len(factors) < newRank:
continue
- found = True
- # escape_counter breaks while loop if it continues on for too long
- escape_counter = 0
- while found:
+ # escape_counter limits the generation of new shapes to a reasonable time
+ for escape_counter in range(100):
+
+ # Generate the new shape of the chosen new rank
newShape = []
- new_shape_inferred = []
- # Generate newShape ensuring it isn't a duplicate
remainingElements = totalElements
shuffledFactors = testGen.rng.permutation(factors)
- inferred_dim = testGen.rng.integers(1, newRank + 1)
for i in range(1, newRank):
# pick rank-1 factors
newShape.append(shuffledFactors[0])
remainingElements = remainingElements // shuffledFactors[0]
- if i == inferred_dim:
- new_shape_inferred.append(-1)
- else:
- new_shape_inferred.append(shuffledFactors[0])
shuffledFactors = testGen.rng.permutation(
TosaArgGen.getFactors(remainingElements)
)
newShape.append(remainingElements)
- if inferred_dim == newRank:
- new_shape_inferred.append(-1)
- else:
- new_shape_inferred.append(remainingElements)
# Check for duplicates
- found = False
+ duplicate = False
for name, args_dict in arg_list:
if args_dict["new_shape"] == newShape:
- found = True
+ duplicate = True
break
- escape_counter += 1
- if escape_counter >= 100:
- break
-
- if not found:
- if error_name in [
- ErrorIf.ReshapeOutputSizeNonInteger,
- ErrorIf.ReshapeOutputSizeMultiInference,
- ]:
- if newRank < 2:
- # Need at least two dimensions
- continue
- # NOTE: Change inferred_dim starting offset from 1 to 0
- inferred_dim -= 1
- extra_dim = inferred_dim + testGen.rng.integers(1, newRank)
- extra_dim = extra_dim % newRank
- assert extra_dim != inferred_dim
- if error_name == ErrorIf.ReshapeOutputSizeNonInteger:
- elements = 1
- for i, dim_value in enumerate(new_shape_inferred):
- if i != inferred_dim and i != extra_dim:
- elements *= dim_value
- dim_value = new_shape_inferred[extra_dim]
- while totalElements % (elements * dim_value) == 0:
- dim_value += 1
- new_shape_inferred[extra_dim] = dim_value
- else:
- assert error_name == ErrorIf.ReshapeOutputSizeMultiInference
- new_shape_inferred[extra_dim] = -1
- else:
- arg_list.append(
- (
- "perm{}_rank{}_outdefined".format(p, newRank),
- {"new_shape": newShape},
- )
- )
- if error_name != ErrorIf.TensorSizeInputOutputMismatch:
- arg_list.append(
- (
- "perm{}_rank{}_outinferred".format(p, newRank),
- {"new_shape": new_shape_inferred},
- )
+ if not duplicate:
+ outShape = "x".join([str(x) for x in newShape])
+ arg_list.append(
+ (
+ "perm{}_rank{}_out{}".format(p, newRank, outShape),
+ {"new_shape": newShape},
)
+ )
+ # Found an output shape for this permutation
+ break
# Now add data generator types
arg_list = TosaArgGen._add_data_generators(
diff --git a/verif/generator/tosa_error_if.py b/verif/generator/tosa_error_if.py
index 5dd785f..7f719ee 100644
--- a/verif/generator/tosa_error_if.py
+++ b/verif/generator/tosa_error_if.py
@@ -2519,56 +2519,6 @@ class TosaErrorValidator:
return info_dict
@staticmethod
- def evReshapeOutputSizeMultiInference(check=False, **kwargs):
- error_name = ErrorIf.ReshapeOutputSizeMultiInference
- param_reqs = {"rank": None, "dtype": None, "shape": None}
- error_result = False
- error_reason = "Reshape output tensor contains more than one inferred dimension"
-
- if check:
- output_shape = kwargs["output_shape"]
- inferences = 0
- for dim in output_shape:
- if dim == -1:
- inferences += 1
- if inferences > 1:
- error_result = True
-
- info_dict = {
- "error_name": error_name,
- "error_result": error_result,
- "error_reason": error_reason,
- "param_reqs": param_reqs,
- }
- return info_dict
-
- @staticmethod
- def evReshapeOutputSizeNonInteger(check=False, **kwargs):
- error_name = ErrorIf.ReshapeOutputSizeNonInteger
- param_reqs = {"rank": None, "dtype": None, "shape": None}
- error_result = False
- error_reason = "Reshape inferred output tensor dimension is non-integer"
-
- if check:
- input_shape = kwargs["input_shape"]
- output_shape = kwargs["output_shape"]
- input_size = np.prod(input_shape)
- output_size = 1
- for dim in output_shape:
- if dim != -1:
- output_size *= dim
- if -1 in output_shape and input_size % output_size != 0:
- error_result = True
-
- info_dict = {
- "error_name": error_name,
- "error_result": error_result,
- "error_reason": error_reason,
- "param_reqs": param_reqs,
- }
- return info_dict
-
- @staticmethod
def calculateBroadcastShape(input_shape_a, input_shape_b):
if input_shape_a is not None and input_shape_b is not None:
calculated_shape = input_shape_a.copy()
diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py
index ee935d4..2290c54 100644
--- a/verif/generator/tosa_test_gen.py
+++ b/verif/generator/tosa_test_gen.py
@@ -4180,8 +4180,6 @@ class TosaTestGen:
TosaErrorValidator.evWrongOutputType,
TosaErrorValidator.evWrongInputList,
TosaErrorValidator.evWrongOutputList,
- TosaErrorValidator.evReshapeOutputSizeMultiInference,
- TosaErrorValidator.evReshapeOutputSizeNonInteger,
),
"data_gen": {
"fp": (gtu.DataGenType.PSEUDO_RANDOM,),