diff options
author | Kevin Cheng <kevin.cheng@arm.com> | 2020-11-11 13:54:06 -0800 |
---|---|---|
committer | Kevin Cheng <kevin.cheng@arm.com> | 2020-11-12 11:47:16 -0800 |
commit | aee1facbde25caf27cc34e5ec08eb8bba6af8e18 (patch) | |
tree | 0ff32b95e6f32444445ca01c1b47835b52fb955f /verif | |
parent | 99bea145a050e12f1b5f8301979713d9a9b04e12 (diff) | |
download | reference_model-aee1facbde25caf27cc34e5ec08eb8bba6af8e18.tar.gz |
Implement and add unit tests for MUL and ARITHMETIC_RIGHT_SHIFT
add .clang-format
Add expected failure for RESIZE and RESCALE unit tests
Signed-off-by: Kevin Cheng <kevin.cheng@arm.com>
Change-Id: I33c8afdc8998e8518f2b0e5fabddd36ce3aa2ee9
Diffstat (limited to 'verif')
-rw-r--r-- | verif/tosa/ArithmeticRightShiftAttribute.py | 45 | ||||
-rw-r--r-- | verif/tosa/Attribute.py | 7 | ||||
-rw-r--r-- | verif/tosa/MulAttribute.py | 45 | ||||
-rw-r--r-- | verif/tosa_serializer.py | 18 | ||||
-rw-r--r-- | verif/tosa_test_gen.py | 103 |
5 files changed, 205 insertions, 13 deletions
diff --git a/verif/tosa/ArithmeticRightShiftAttribute.py b/verif/tosa/ArithmeticRightShiftAttribute.py new file mode 100644 index 0000000..eaa52ab --- /dev/null +++ b/verif/tosa/ArithmeticRightShiftAttribute.py @@ -0,0 +1,45 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# Copyright (c) 2020, 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. + + +# namespace: tosa + +import flatbuffers + +class ArithmeticRightShiftAttribute(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAsArithmeticRightShiftAttribute(cls, buf, offset): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = ArithmeticRightShiftAttribute() + x.Init(buf, n + offset) + return x + + # ArithmeticRightShiftAttribute + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # ArithmeticRightShiftAttribute + def Round(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos)) + return False + +def ArithmeticRightShiftAttributeStart(builder): builder.StartObject(1) +def ArithmeticRightShiftAttributeAddRound(builder, round): builder.PrependBoolSlot(0, round, 0) +def ArithmeticRightShiftAttributeEnd(builder): return builder.EndObject() diff --git a/verif/tosa/Attribute.py b/verif/tosa/Attribute.py index a4d96e0..5d79a08 100644 --- a/verif/tosa/Attribute.py +++ b/verif/tosa/Attribute.py @@ -30,7 +30,8 @@ class Attribute(object): ResizeAttribute = 9 ClampAttribute = 10 RescaleAttribute = 11 - CustomAttribute = 12 - CondIfAttribute = 13 - WhileLoopAttribute = 14 + MulAttribute = 12 + ArithmeticRightShiftAttribute = 13 + CondIfAttribute = 14 + WhileLoopAttribute = 15 diff --git a/verif/tosa/MulAttribute.py b/verif/tosa/MulAttribute.py new file mode 100644 index 0000000..f45b285 --- /dev/null +++ b/verif/tosa/MulAttribute.py @@ -0,0 +1,45 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# Copyright (c) 2020, 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. + + +# namespace: tosa + +import flatbuffers + +class MulAttribute(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAsMulAttribute(cls, buf, offset): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = MulAttribute() + x.Init(buf, n + offset) + return x + + # MulAttribute + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # MulAttribute + def Shift(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) + return 0 + +def MulAttributeStart(builder): builder.StartObject(1) +def MulAttributeAddShift(builder, shift): builder.PrependInt32Slot(0, shift, 0) +def MulAttributeEnd(builder): return builder.EndObject() diff --git a/verif/tosa_serializer.py b/verif/tosa_serializer.py index 7ba68c3..07e0e1a 100644 --- a/verif/tosa_serializer.py +++ b/verif/tosa_serializer.py @@ -247,6 +247,24 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.bools.append((a.RescaleAttributeAddPerChannel, per_channel)) + def MulAttribute(self, shift): + from tosa import MulAttribute as a, Attribute + + self.utype = Attribute.Attribute().MulAttribute + self.optFcns = (a.MulAttributeStart, a.MulAttributeEnd) + + self.ints.append((a.MulAttributeAddShift, + shift)) + + def ArithmeticRightShiftAttribute(self, round): + from tosa import ArithmeticRightShiftAttribute as a, Attribute + + self.utype = Attribute.Attribute().ArithmeticRightShiftAttribute + self.optFcns = (a.ArithmeticRightShiftAttributeStart, a.ArithmeticRightShiftAttributeEnd) + + self.bools.append((a.ArithmeticRightShiftAttributeAddRound, + round)) + def CustomAttribute(self, identifier): from tosa import CustomAttribute as a, Attribute diff --git a/verif/tosa_test_gen.py b/verif/tosa_test_gen.py index dc2d803..302e4f4 100644 --- a/verif/tosa_test_gen.py +++ b/verif/tosa_test_gen.py @@ -489,6 +489,30 @@ class TosaArgGen: return arg_list + @staticmethod + def agMul(testGen, opName, shapeList, dtype): + arg_list = [] + + if dtype is DType.INT32: + for p in range(testGen.args.num_rand_permutations): + + shift = testGen.randInt(0, 32) + + arg_list.append(('perm{}_shift{}'.format(p, shift), [shift])) + else: + arg_list.append(('shift0', [0])) + + return arg_list + + @staticmethod + def agArithmeticRightShift(testGen, opName, shapeList, dtype): + arg_list = [] + + arg_list.append(('roundTrue', [True])) + arg_list.append(('roundFalse', [False])) + + return arg_list + # Helper function for reshape. Gets some factors of a larger number. @staticmethod def getFactors(val, start=1): @@ -647,7 +671,7 @@ class TosaArgGen: arg_list.append(('mode{}_shift{}_odim{}x{}_out{}_st{}x{}_off{}x{}'.format(m, shift, output_dims[0], output_dims[1], testGen.typeStr(outputDType), stride[0], stride[1], offset[0], offset[1]), - [m, stride, offset, shift, output_dims, outputDType])) + [m, stride, offset, shift, output_dims, dtype, outputDType])) return arg_list @@ -850,7 +874,16 @@ class TosaTestGen: self.ser.addOperator(op, [a.name, b.name], [result_tens.name]) return result_tens - def build_mul(self, op, a, b): + def build_arithmetic_right_shift(self, op, a, b, round): + result_tens = OutputShaper.binaryBroadcastOp(self.ser, a, b) + + attr = ts.TosaSerializerAttribute() + attr.ArithmeticRightShiftAttribute(round) + + self.ser.addOperator(op, [a.name, b.name], [result_tens.name], attr) + return result_tens + + def build_mul(self, op, a, b, shift): result_tens = OutputShaper.binaryBroadcastOp(self.ser, a, b) # Special for multiply: @@ -858,7 +891,10 @@ class TosaTestGen: if a.dtype != DType.FLOAT: result_tens.setDtype(DType.INT32) - self.ser.addOperator(op, [a.name, b.name], [result_tens.name]) + attr = ts.TosaSerializerAttribute() + attr.MulAttribute(shift) + + self.ser.addOperator(op, [a.name, b.name], [result_tens.name], attr) return result_tens def build_table(self, op, a): @@ -1121,8 +1157,8 @@ class TosaTestGen: return result_tens - def build_resize(self, op, input, mode, stride, offset, shift, output_dims, output_dtype): - result_tens = OutputShaper.resizeOp(self.ser, input, mode, stride, offset, shift, output_dims, output_dtype) + def build_resize(self, op, input, mode, stride, offset, shift, output_dims, input_dtype, output_dtype): + result_tens = OutputShaper.resizeOp(self.ser, input, mode, stride, offset, shift, output_dims, input_dtype, output_dtype) attr = ts.TosaSerializerAttribute() attr.ResizeAttribute(output_dims, stride, offset, shift, mode) @@ -1191,6 +1227,8 @@ class TosaTestGen: for i in range(nc): multiplier_arr[i], shift_arr[i] = TosaQuantGen.computeMultiplierAndShift(scale_arr[i], scale32) + if shift_arr[i] < 2 or shift_arr[i] > 62: + self.ser.setExpectedFailure(True, 'OpRescale: invalid shift value') #print('multiplier {} shift {} inzp {} outzp {}'.format(multiplier_arr, shift_arr, input_zp, output_zp)) @@ -1413,8 +1451,30 @@ class TosaTestGen: # Build the random tensor operands and the test tens = [] - tens.extend(self.buildPlaceholderTensors(shapeList[0:pCount], dtype)) - tens.extend(self.buildConstTensors(shapeList[pCount:], dtype)) + + # If test is ArithmeticRightShift, force value of operand[1] to be within [0, num_bits] + if op['op'] == Op.ARITHMETIC_RIGHT_SHIFT: + assert pCount == 2 and cCount == 0, 'Op.ArithmeticRightShift must have 2 placeholders, 0 consts' + + placeholders = [] + for idx, shape in enumerate(shapeList[:]): + if idx == 1: + if dtype == DType.INT8: + arr = np.int32(self.rng.integers(low=0, high=8, size=shape)) + elif dtype == DType.INT16: + arr = np.int32(self.rng.integers(low=0, high=16, size=shape)) + elif dtype == DType.INT32: + arr = np.int32(self.rng.integers(low=0, high=32, size=shape)) + else: + raise Exception('OpArithmeticRightShift: invalid input dtype') + else: + arr = self.getRandTensor(shapeList[0], dtype) + placeholders.append(self.ser.addPlaceholder(shape, dtype, Usage.ACTIVATION, [], arr)) + + tens.extend(placeholders) + else: + tens.extend(self.buildPlaceholderTensors(shapeList[0:pCount], dtype)) + tens.extend(self.buildConstTensors(shapeList[pCount:], dtype)) if qgen is not None: qinfo = qgen(self, op, dtype) @@ -1536,7 +1596,7 @@ class TosaTestGen: 'arithmetic_right_shift': { 'op': Op.ARITHMETIC_RIGHT_SHIFT, 'operands': (2, 0), - 'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None), + 'build_fcn': (build_arithmetic_right_shift, TosaTensorGen.tgBroadcastFuzz, TosaArgGen.agArithmeticRightShift), 'types': TYPE_PURE_INT }, 'bitwise_and': @@ -1602,7 +1662,7 @@ class TosaTestGen: 'mul': { 'op': Op.MUL, 'operands': (2, 0), - 'build_fcn': (build_mul, TosaTensorGen.tgBroadcastFuzz, None), + 'build_fcn': (build_mul, TosaTensorGen.tgBroadcastFuzz, TosaArgGen.agMul), 'types': TYPE_PURE_INT_FP }, 'pow': @@ -2271,13 +2331,36 @@ class OutputShaper: return ser.addOutput(input.shape, DType.INT32, input.usage, input.dformat) @staticmethod - def resizeOp(ser, input, mode, stride, offset, shift, output_dims, output_dtype): + def resizeOp(ser, input, mode, stride, offset, shift, output_dims, input_dtype, output_dtype): output_dims = [input.shape[0], output_dims[0], output_dims[1], input.shape[3]] if stride[0] <= 0 or stride[1] <= 0: ser.setExpectedFailure(True, 'Negative or zero stride') + if mode == ResizeMode.BILINEAR: + if input_dtype == DType.INT8: + if output_dtype != DType.INT32: + ser.setExpectedFailure(True, 'Invalid output data type') + elif input_dtype == DType.INT16: + if output_dtype != DType.INT48: + ser.setexpectedfailure(true, 'Invalid output data type') + else: + ser.setexpectedfailure(true, 'Invalid input data type') + + elif mode == ResizeMode.NEAREST: + if input_dtype == DType.INT8: + if output_dtype != DType.INT8: + ser.setExpectedFailure(True, 'Invalid output data type') + elif input_dtype == DType.INT16: + if output_dtype != DType.INT16: + ser.setexpectedfailure(true, 'Invalid output data type') + else: + ser.setexpectedfailure(true, 'Invalid input data type') + + else: + ser.setexpectedfailure(true, 'Invalid resize mode') + return ser.addOutput(output_dims, output_dtype, input.usage, input.dformat) @staticmethod |