aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Johnson <jeremy.johnson@arm.com>2022-04-05 14:31:37 +0100
committerJeremy Johnson <jeremy.johnson@arm.com>2022-04-05 16:05:19 +0100
commit7de9b456620c0b9df20c1bed466779149c4112fd (patch)
treeb78712e4530feb7cddfd17d92c75334d0d698db9
parent5d1a347fc2d34f0aba9ac24d3e17d05292d727f0 (diff)
downloadreference_model-7de9b456620c0b9df20c1bed466779149c4112fd.tar.gz
Add missing REQUIREs check to REDUCE_SUM in refmodel
And limit REDUCE_SUM test values to within int32 Signed-off-by: Jeremy Johnson <jeremy.johnson@arm.com> Change-Id: I4d902b245d17eb343cfb2bbc23d9db28c1d1f4c3
-rw-r--r--reference_model/src/ops/op_factory.cc2
-rw-r--r--reference_model/src/ops/reduction.cc27
-rw-r--r--reference_model/src/ops/reduction.h10
-rw-r--r--verif/generator/tosa_test_gen.py15
4 files changed, 52 insertions, 2 deletions
diff --git a/reference_model/src/ops/op_factory.cc b/reference_model/src/ops/op_factory.cc
index d42c84a..6edd63f 100644
--- a/reference_model/src/ops/op_factory.cc
+++ b/reference_model/src/ops/op_factory.cc
@@ -273,7 +273,7 @@ GraphNode* OpFactory::newOp(SubgraphTraverser* sgt,
break;
case Op_REDUCE_SUM:
DEF_FACTORY_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSum, FLOAT);
- DEF_FACTORY_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSum, INT32);
+ DEF_FACTORY_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSumInt, INT32);
break;
// data layout
diff --git a/reference_model/src/ops/reduction.cc b/reference_model/src/ops/reduction.cc
index 8c1c4d0..18fac44 100644
--- a/reference_model/src/ops/reduction.cc
+++ b/reference_model/src/ops/reduction.cc
@@ -128,6 +128,31 @@ int OpReduceSum<Rank, Dtype>::eval()
return GraphNode::eval();
}
+struct SumRequiresReducer {
+ static const bool PacketAccess = false;
+ SumRequiresReducer(SubgraphTraverser* parent_sgt) : parent_sgt(parent_sgt) {}
+ void reduce(const int32_t val, int32_t* accum) {
+ int64_t res_in_64 = static_cast<int64_t>(*accum) + val;
+ int64_t i32_max_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
+ int64_t i32_min_in_64 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
+ REQUIRE(res_in_64 <= i32_max_in_64 && res_in_64 >= i32_min_in_64, "OpReduceSum: result not in i32 range");
+ *accum = static_cast<int32_t>(res_in_64);
+ }
+ int32_t initialize() const { return 0; }
+ int32_t finalize(const int32_t accum) const { return accum; }
+
+ private:
+ SubgraphTraverser* parent_sgt;
+};
+
+template <int Rank, DType Dtype>
+int OpReduceSumInt<Rank, Dtype>::eval()
+{
+ this->out->getTensor() = this->in->getTensor().reduce(this->dims, SumRequiresReducer(this->parent_sgt)).reshape(this->out->getTensor().dimensions());
+
+ return GraphNode::eval();
+}
+
// template explicit instantiation
DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceAll, BOOL);
@@ -146,4 +171,4 @@ DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceMin, INT32);
DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceProduct, FLOAT);
DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSum, FLOAT);
-DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSum, INT32);
+DEF_INSTANTIATE_RANK1_6_ONE_RANK_ONE_TYPE(OpReduceSumInt, INT32);
diff --git a/reference_model/src/ops/reduction.h b/reference_model/src/ops/reduction.h
index f4e29b9..f3407f4 100644
--- a/reference_model/src/ops/reduction.h
+++ b/reference_model/src/ops/reduction.h
@@ -104,6 +104,16 @@ public:
virtual int eval();
};
+template <int Rank, DType Dtype>
+class OpReduceSumInt : public ReduceNode<Rank, Dtype>
+{
+public:
+ OpReduceSumInt(SubgraphTraverser* sgt_, TosaAttributeBase* attribute_, TosaQuantInfoBase* qinfo_, uint64_t id_)
+ : ReduceNode<Rank, Dtype>(sgt_, Op_REDUCE_SUM, attribute_, id_)
+ {}
+ virtual int eval();
+};
+
}; // namespace TosaReference
#endif
diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py
index 64f0c5e..80b2981 100644
--- a/verif/generator/tosa_test_gen.py
+++ b/verif/generator/tosa_test_gen.py
@@ -6063,6 +6063,21 @@ class TosaTestGen:
self.ser.addPlaceholder(shapeList[1], dtypeList[1], b_arr)
)
tens.extend(placeholders)
+ elif op["op"] == Op.REDUCE_SUM and dtypeList[0] == DType.INT32:
+ assert (
+ pCount == 1 and cCount == 0
+ ), "Op.REDUCE_SUM must have 1 placeholders, 0 consts"
+ # Limit values so that the sum cannot exceed the range of an int32 during
+ # summation of any axis
+ range_val = int((1 << 31) / max(shapeList[0]))
+ values_arr = np.int32(
+ self.rng.integers(low=-range_val, high=range_val, size=shapeList[0])
+ )
+ placeholders = []
+ placeholders.append(
+ self.ser.addPlaceholder(shapeList[0], dtypeList[0], values_arr)
+ )
+ tens.extend(placeholders)
else:
tens.extend(
self.buildPlaceholderTensors(shapeList[0:pCount], dtypeList[0:pCount])