aboutsummaryrefslogtreecommitdiff
path: root/verif
diff options
context:
space:
mode:
Diffstat (limited to 'verif')
-rw-r--r--verif/tosa/Op.py21
-rw-r--r--verif/tosa/ResizeAttribute.py54
-rw-r--r--verif/tosa/Version.py4
-rw-r--r--verif/tosa_serializer.py21
-rw-r--r--verif/tosa_test_gen.py175
5 files changed, 226 insertions, 49 deletions
diff --git a/verif/tosa/Op.py b/verif/tosa/Op.py
index 09f1364..ea9cdfe 100644
--- a/verif/tosa/Op.py
+++ b/verif/tosa/Op.py
@@ -77,14 +77,15 @@ class Op(object):
TILE = 56
TRANSPOSE = 57
GATHER = 58
- RESIZE = 59
- CAST = 60
- RESCALE = 61
- CONST = 62
- PLACEHOLDER = 63
- IDENTITY = 64
- IDENTITYN = 65
- CUSTOM = 66
- COND_IF = 67
- WHILE_LOOP = 68
+ SCATTER = 59
+ RESIZE = 60
+ CAST = 61
+ RESCALE = 62
+ CONST = 63
+ PLACEHOLDER = 64
+ IDENTITY = 65
+ IDENTITYN = 66
+ CUSTOM = 67
+ COND_IF = 68
+ WHILE_LOOP = 69
diff --git a/verif/tosa/ResizeAttribute.py b/verif/tosa/ResizeAttribute.py
index 1e6941f..35be73a 100644
--- a/verif/tosa/ResizeAttribute.py
+++ b/verif/tosa/ResizeAttribute.py
@@ -107,13 +107,57 @@ class ResizeAttribute(object):
return 0
# ResizeAttribute
- def Mode(self):
+ def StrideFp(self, j):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+ if o != 0:
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+ return 0
+
+ # ResizeAttribute
+ def StrideFpAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
+ return 0
+
+ # ResizeAttribute
+ def StrideFpLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ResizeAttribute
+ def OffsetFp(self, j):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+ if o != 0:
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+ return 0
+
+ # ResizeAttribute
+ def OffsetFpAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
+ return 0
+
+ # ResizeAttribute
+ def OffsetFpLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ResizeAttribute
+ def Mode(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+ if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
return 0
-def ResizeAttributeStart(builder): builder.StartObject(5)
+def ResizeAttributeStart(builder): builder.StartObject(7)
def ResizeAttributeAddOutputSize(builder, outputSize): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(outputSize), 0)
def ResizeAttributeStartOutputSizeVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def ResizeAttributeAddStride(builder, stride): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(stride), 0)
@@ -121,5 +165,9 @@ def ResizeAttributeStartStrideVector(builder, numElems): return builder.StartVec
def ResizeAttributeAddOffset(builder, offset): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(offset), 0)
def ResizeAttributeStartOffsetVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def ResizeAttributeAddShift(builder, shift): builder.PrependInt32Slot(3, shift, 0)
-def ResizeAttributeAddMode(builder, mode): builder.PrependUint32Slot(4, mode, 0)
+def ResizeAttributeAddStrideFp(builder, strideFp): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(strideFp), 0)
+def ResizeAttributeStartStrideFpVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def ResizeAttributeAddOffsetFp(builder, offsetFp): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(offsetFp), 0)
+def ResizeAttributeStartOffsetFpVector(builder, numElems): return builder.StartVector(4, numElems, 4)
+def ResizeAttributeAddMode(builder, mode): builder.PrependUint32Slot(6, mode, 0)
def ResizeAttributeEnd(builder): return builder.EndObject()
diff --git a/verif/tosa/Version.py b/verif/tosa/Version.py
index ddfdb2d..e327507 100644
--- a/verif/tosa/Version.py
+++ b/verif/tosa/Version.py
@@ -45,7 +45,7 @@ class Version(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
- return 20
+ return 21
# Version
def _patch(self):
@@ -63,7 +63,7 @@ class Version(object):
def VersionStart(builder): builder.StartObject(4)
def VersionAdd_major(builder, Major): builder.PrependInt32Slot(0, Major, 0)
-def VersionAdd_minor(builder, Minor): builder.PrependInt32Slot(1, Minor, 20)
+def VersionAdd_minor(builder, Minor): builder.PrependInt32Slot(1, Minor, 21)
def VersionAdd_patch(builder, Patch): builder.PrependInt32Slot(2, Patch, 0)
def VersionAdd_experimental(builder, Experimental): builder.PrependBoolSlot(3, Experimental, 0)
def VersionEnd(builder): return builder.EndObject()
diff --git a/verif/tosa_serializer.py b/verif/tosa_serializer.py
index 07e0e1a..3b7e339 100644
--- a/verif/tosa_serializer.py
+++ b/verif/tosa_serializer.py
@@ -63,12 +63,14 @@ class TosaSerializerUnion:
self.floats = []
self.strings = []
self.intvecs = []
+ self.fpvecs = []
def serialize(self, builder):
# We have to build strings and vectors first
strList = []
intVecList = []
+ fpVecList = []
for fcn, val in self.strings:
strList.append((fcn, builder.CreateString(val)))
@@ -76,6 +78,9 @@ class TosaSerializerUnion:
for fcn, val in self.intvecs:
intVecList.append((fcn, TosaSerializer.serializeInt32Vec(builder, val)))
+ for fcn, val in self.fpvecs:
+ fpVecList.append((fcn, TosaSerializer.serializeFpVec(builder, val)))
+
startFcn, endFcn = self.optFcns
# Then serialize the options object from the list of primitives and
@@ -96,6 +101,9 @@ class TosaSerializerUnion:
for fcn, val in intVecList:
fcn(builder, val)
+ for fcn, val in fpVecList:
+ fcn(builder, val)
+
return endFcn(builder)
class TosaSerializerAttribute(TosaSerializerUnion):
@@ -193,7 +201,7 @@ class TosaSerializerAttribute(TosaSerializerUnion):
self.intvecs.append((a.TileAttributeAddMultiples,
multiples))
- def ResizeAttribute(self, output_size, stride, offset, shift, mode):
+ def ResizeAttribute(self, output_size, stride, offset, shift, stride_fp, offset_fp, mode):
from tosa import ResizeAttribute as a, Attribute
self.utype = Attribute.Attribute().ResizeAttribute
@@ -207,6 +215,10 @@ class TosaSerializerAttribute(TosaSerializerUnion):
offset))
self.ints.append((a.ResizeAttributeAddShift,
shift))
+ self.fpvecs.append((a.ResizeAttributeAddStrideFp,
+ stride_fp))
+ self.fpvecs.append((a.ResizeAttributeAddOffsetFp,
+ offset_fp))
self.ints.append((a.ResizeAttributeAddMode,
mode))
@@ -692,6 +704,13 @@ class TosaSerializer:
return builder.EndVector(len(vec))
@staticmethod
+ def serializeFpVec(builder, vec):
+ builder.StartVector(4, len(vec), 4)
+ for v in vec[::-1]:
+ builder.PrependFloat32(v)
+ return builder.EndVector(len(vec))
+
+ @staticmethod
def serializeObjVec(builder, vec, start_fcn):
serialized_vec = []
for v in vec[::-1]:
diff --git a/verif/tosa_test_gen.py b/verif/tosa_test_gen.py
index 302e4f4..0e57a7b 100644
--- a/verif/tosa_test_gen.py
+++ b/verif/tosa_test_gen.py
@@ -158,6 +158,29 @@ class TosaTensorGen():
return shape_list
@staticmethod
+ def tgScatter(testGen, opName, rank):
+ pl, const = opName['operands']
+
+ assert(pl == 2)
+ assert(const == 0)
+ assert(rank == 3)
+
+ values_in_shape = testGen.makeShape(rank)
+
+ # Constrict the batch size?
+ if testGen.args.max_batch_size:
+ values_in_shape[0] = (values_in_shape[0] % testGen.args.max_batch_size) + 1
+
+ W = testGen.randInt(testGen.args.tensor_shape_range[0], testGen.args.tensor_shape_range[1])
+ input_shape = [values_in_shape[0], W, values_in_shape[2]]
+
+ shape_list = []
+ shape_list.append(values_in_shape.copy())
+ shape_list.append(input_shape.copy())
+
+ return shape_list
+
+ @staticmethod
def tgBroadcastFuzz(testGen, op, rank):
shape = testGen.makeShape(rank)
@@ -650,6 +673,8 @@ class TosaArgGen:
outputDTypeList = [ DType.INT8 ]
elif m == ResizeMode.BILINEAR and dtype == DType.INT16:
outputDTypeList = [ DType.INT48 ]
+ elif dtype == DType.FLOAT:
+ outputDTypeList = [ DType.FLOAT ]
else:
continue
@@ -659,19 +684,52 @@ class TosaArgGen:
# Randomly generate legal output dimensions and shift
# and then compute the stride and offset based on them
output_dims = [ testGen.randInt(), testGen.randInt() ]
-
- shift = testGen.randInt(1, 11)
-
- stride = [ (ifm_shape[1] << shift) // output_dims[0],
- (ifm_shape[2] << shift) // output_dims[1] ]
-
- offset = [ testGen.randInt(-stride[0], (ifm_shape[1] << shift) - (output_dims[0] - 1) * stride[0]),
- testGen.randInt(-stride[1], (ifm_shape[2] << shift) - (output_dims[1] - 1) * stride[1]) ]
-
- 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, dtype, outputDType]))
+ in_center_h = (ifm_shape[1] - 1) / 2.0
+ in_center_w = (ifm_shape[2] - 1) / 2.0
+ out_center_h = (output_dims[0] - 1) / 2.0
+ out_center_w = (output_dims[1] - 1) / 2.0
+
+ fp_stride_y = float(ifm_shape[1]) / float(output_dims[0])
+ fp_stride_x = float(ifm_shape[2]) / float(output_dims[1])
+ fp_offset_y = in_center_h - fp_stride_y * out_center_h
+ fp_offset_x = in_center_w - fp_stride_x * out_center_w
+
+ if outputDType == DType.FLOAT:
+ shift = 0
+ stride = [0, 0]
+ offset = [0, 0]
+ stride_fp = [ fp_stride_y, fp_stride_x]
+ offset_fp = [ fp_offset_y, fp_offset_x]
+ arg_list.append(('mode{}_odim{}x{}_out{}_st{:.2f}x{:.2f}_off{:.2f}x{:.2f}'.format(m, output_dims[0], output_dims[1],
+ testGen.typeStr(outputDType), stride_fp[0], stride_fp[1],
+ offset_fp[0], offset_fp[1]),
+ [m, stride, offset, shift, stride_fp, offset_fp, output_dims, dtype, outputDType]))
+ else:
+ shift = 11
+ unit = float(1 << shift)
+ stride_y = int(round(fp_stride_y * unit))
+ stride_x = int(round(fp_stride_x * unit))
+ offset_y = int(round(fp_offset_y * unit))
+ offset_x = int(round(fp_offset_x * unit))
+
+ while (stride_y >= 32768 or stride_x >= 32768 or offset_y >= 32768 or offset_x >= 32768 or offset_y < -32768 or offset_x < -32768):
+ shift = shift - 1
+ unit = float(1 << shift)
+ stride_y = int(round(fp_stride_y * unit))
+ stride_x = int(round(fp_stride_x * unit))
+ offset_y = int(round(fp_offset_y * unit))
+ offset_x = int(round(fp_offset_x * unit))
+
+ stride = [ stride_y, stride_x]
+ offset = [ offset_y, offset_x]
+
+ stride_fp = [0.0, 0.0]
+ offset_fp = [0.0, 0.0]
+
+ 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, stride_fp, offset_fp, output_dims, dtype, outputDType]))
return arg_list
@@ -1139,29 +1197,44 @@ class TosaTestGen:
return result_tens
- def build_gather(self, op, values, axis):
+ def build_gather(self, op, values):
# Create a new indicies tensor
# here with data that doesn't exceed the dimensions of the values tensor
- max_val = values.shape[axis]
- indicies_arr = np.int32(self.rng.integers(low=0, high=max_val, size=[self.randInt(1, max_val + 1)]))
+ K = values.shape[1] # K
+ W = self.randInt(self.args.tensor_shape_range[0], self.args.tensor_shape_range[1]) # W
+ indicies_arr = np.int32(self.rng.integers(low=0, high=K, size=[values.shape[0], W])) # (N, W)
indicies = self.ser.addConst(indicies_arr.shape, DType.INT32, Usage.INDEX, [], indicies_arr)
- result_tens = OutputShaper.gatherOp(self.ser, values, indicies, axis)
+ result_tens = OutputShaper.gatherOp(self.ser, values, indicies)
- attr = ts.TosaSerializerAttribute()
- attr.AxisAttribute(axis)
+ self.ser.addOperator(op, [values.name, indicies.name], [result_tens.name])
- self.ser.addOperator(op, [values.name, indicies.name], [result_tens.name], attr)
+ return result_tens
+
+ def build_scatter(self, op, values_in, input):
+
+ # Create a new indicies tensor
+ # here with data that doesn't exceed the dimensions of the values_in tensor
+
+ K = values_in.shape[1] # K
+ W = input.shape[1] # W
+ indicies_arr = np.int32(self.rng.integers(low=0, high=K, size=[values_in.shape[0], W])) # (N, W)
+ indicies = self.ser.addConst(indicies_arr.shape, DType.INT32, Usage.INDEX, [], indicies_arr)
+
+ result_tens = OutputShaper.scatterOp(self.ser, values_in, indicies, input)
+
+ self.ser.addOperator(op, [values_in.name, indicies.name, input.name], [result_tens.name])
return result_tens
- 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)
+ def build_resize(self, op, input, mode, stride, offset, shift, stride_fp, offset_fp, output_dims, input_dtype, output_dtype):
+ result_tens = OutputShaper.resizeOp(self.ser, input, mode, stride, offset, shift, stride_fp, offset_fp, output_dims, input_dtype, output_dtype)
attr = ts.TosaSerializerAttribute()
- attr.ResizeAttribute(output_dims, stride, offset, shift, mode)
+
+ attr.ResizeAttribute(output_dims, stride, offset, shift, stride_fp, offset_fp, mode)
self.ser.addOperator(op, [input.name], [result_tens.name], attr)
return result_tens
@@ -1966,10 +2039,20 @@ class TosaTestGen:
# Scatter/Gather
'gather':
{ 'op': Op.GATHER,
+ # Only specify 'values' tensor here. 'indices' is generated in op building stage
'operands': (1, 0),
- 'build_fcn': (build_gather, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
- 'types': TYPE_INT },
+ 'rank': (3, 3),
+ 'build_fcn': (build_gather, TosaTensorGen.tgBasic, None),
+ 'types': TYPE_INT_FP },
+ 'scatter':
+ { 'op': Op.SCATTER,
+ # Only specify 'values_in' tensor here.
+ #'indices' and 'input' are generated in op building stage
+ 'operands': (2, 0),
+ 'rank': (3, 3),
+ 'build_fcn': (build_scatter, TosaTensorGen.tgScatter, None),
+ 'types': TYPE_INT_FP },
# Image operations
'resize':
@@ -1977,7 +2060,7 @@ class TosaTestGen:
'operands': (1, 0),
'rank': (4, 4),
'build_fcn': ( build_resize, TosaTensorGen.tgNHWC, TosaArgGen.agResize),
- 'types': [ DType.INT8, DType.INT16 ] },
+ 'types': [ DType.INT8, DType.INT16, DType.FLOAT ] },
# Data nodes
@@ -2319,11 +2402,27 @@ class OutputShaper:
return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)
@staticmethod
- def gatherOp(ser, values, indicies, axis):
- # indicies minus the axis + values - the indexes used to look up values.
- output_shape = [*values.shape[0:axis], indicies.shape[0], *values.shape[axis+1:]]
+ def gatherOp(ser, values, indices):
+ assert len(values.shape) == 3
+ assert len(indices.shape) == 2
+ assert values.shape[0] == indices.shape[0]
+
+ output_shape = [values.shape[0], indices.shape[1], values.shape[2]]
+
+ return ser.addOutput(output_shape, values.dtype, values.usage, values.dformat)
+
+ @staticmethod
+ def scatterOp(ser, values_in, indices, input):
+ assert len(values_in.shape) == 3
+ assert len(indices.shape) == 2
+ assert len(input.shape) == 3
+ assert values_in.shape[0] == indices.shape[0] # N
+ assert input.shape[1] == indices.shape[1] # W
+ assert values_in.shape[2] == input.shape[2] # C
+
+ output_shape = values_in.shape
- return ser.addOutput(output_shape, values.dtype, indicies.usage, indicies.dformat)
+ return ser.addOutput(output_shape, values_in.dtype, values_in.usage, values_in.dformat)
@staticmethod
def tableOp(ser, input, table):
@@ -2331,12 +2430,16 @@ class OutputShaper:
return ser.addOutput(input.shape, DType.INT32, input.usage, input.dformat)
@staticmethod
- def resizeOp(ser, input, mode, stride, offset, shift, output_dims, input_dtype, output_dtype):
+ def resizeOp(ser, input, mode, stride, offset, shift, stride_fp, offset_fp, 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 input_dtype == DType.FLOAT:
+ if stride_fp[0] <= 0 or stride_fp[1] <= 0:
+ ser.setExpectedFailure(True, 'Negative or zero stride')
+ else:
+ if stride[0] <= 0 or stride[1] <= 0:
+ ser.setExpectedFailure(True, 'Negative or zero stride')
if mode == ResizeMode.BILINEAR:
if input_dtype == DType.INT8:
@@ -2345,6 +2448,9 @@ class OutputShaper:
elif input_dtype == DType.INT16:
if output_dtype != DType.INT48:
ser.setexpectedfailure(true, 'Invalid output data type')
+ elif input_dtype == DType.FLOAT:
+ if output_dtype != DType.FLOAT:
+ ser.setexpectedfailure(true, 'Invalid output data type')
else:
ser.setexpectedfailure(true, 'Invalid input data type')
@@ -2355,6 +2461,9 @@ class OutputShaper:
elif input_dtype == DType.INT16:
if output_dtype != DType.INT16:
ser.setexpectedfailure(true, 'Invalid output data type')
+ elif input_dtype == DType.FLOAT:
+ if output_dtype != DType.FLOAT:
+ ser.setexpectedfailure(true, 'Invalid output data type')
else:
ser.setexpectedfailure(true, 'Invalid input data type')