diff options
author | Jeremy Johnson <jeremy.johnson@arm.com> | 2022-04-05 14:31:37 +0100 |
---|---|---|
committer | Jeremy Johnson <jeremy.johnson@arm.com> | 2022-04-05 16:05:19 +0100 |
commit | 7de9b456620c0b9df20c1bed466779149c4112fd (patch) | |
tree | b78712e4530feb7cddfd17d92c75334d0d698db9 | |
parent | 5d1a347fc2d34f0aba9ac24d3e17d05292d727f0 (diff) | |
download | reference_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.cc | 2 | ||||
-rw-r--r-- | reference_model/src/ops/reduction.cc | 27 | ||||
-rw-r--r-- | reference_model/src/ops/reduction.h | 10 | ||||
-rw-r--r-- | verif/generator/tosa_test_gen.py | 15 |
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]) |