#!/usr/bin/env python3

# Copyright (c) 2020-2021, 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.


import numpy as np
import argparse
import sys
import re
import os
import subprocess
import shlex
import json
import glob
import math
import queue
import threading
import traceback
import math

from enum import IntEnum, Enum, unique

import tosa_serializer as ts
from tosa_serializer import *
import tosa

# Convenience variables to the flatc-generated types that should be enums, but aren't
DType = tosa.DType.DType()
Usage = tosa.Usage.Usage()
Format = tosa.Format.Format()
Op    = tosa.Op.Op()
ResizeMode = tosa.ResizeMode.ResizeMode()

class TosaQuantGen:
    '''QuantizedInfo random generator helper functions.  Specify with 'qgen': in the operator defintion'''
    def __init__(self):
        pass

    @staticmethod
    def needsQinfo(op, dtype):
        if dtype == DType.INT8:
            return True
        return False

    @staticmethod
    def qgUnary(testGen, op, dtype):
        qinfo = ts.TosaSerializerQuantInfo()
        if TosaQuantGen.needsQinfo(op, dtype):
            qinfo.UnaryQuantInfo(testGen.randInt(), testGen.randInt())
        else:
            qinfo.UnaryQuantInfo(0, 0)
        return qinfo

    @staticmethod
    def qgConv(testGen, op, dtype):
        qinfo = ts.TosaSerializerQuantInfo()
        if TosaQuantGen.needsQinfo(op, dtype):
            qinfo.ConvQuantInfo(testGen.randInt(), testGen.randInt())
        else:
            qinfo.ConvQuantInfo(0, 0)
        return qinfo

    @staticmethod
    def qgMatmul(testGen, op, dtype):
        qinfo = ts.TosaSerializerQuantInfo()
        if TosaQuantGen.needsQinfo(op, dtype):
            qinfo.MatMulQuantInfo(testGen.randInt(), testGen.randInt())
        else:
            qinfo.MatMulQuantInfo(0, 0)
        return qinfo

    @staticmethod
    def qgPad(testGen, op, dtype):
        qinfo = ts.TosaSerializerQuantInfo()
        if TosaQuantGen.needsQinfo(op, dtype):
            qinfo.PadQuantInfo(testGen.randInt())
        else:
            qinfo.PadQuantInfo(0)
        return qinfo

    @staticmethod
    def computeMultiplierAndShift(scaleFp, scale32):
        # Derived from computeMultiplierAndShiftTosaScale32
        # Provide a floating-point scaling factor and the scale32 parameter
        # to compute the multiplier and shift

        if scale32:
            scaleBits = 31
        else:
            scaleBits = 15

        m, shift = math.frexp(scaleFp)

        if scaleFp < 0.0:
            m = -m

        multiplier = round(m * (1 << scaleBits))
        assert(multiplier <= (1 << scaleBits))

        if multiplier == (1 << scaleBits):
            multiplier = multiplier // 2
            shift = shift + 1

        shift = (-shift) + scaleBits
        #print('scalefp {} scaleBits {} m {} mult {} shift {}'.format(scaleFp, scaleBits, m, multiplier, shift))

        assert(multiplier <= (1 << scaleBits))
        assert(shift >= 0 and shift <= 63)

        return multiplier, shift


class TosaTensorGen():
    ''' Tensor generators create a shape list for the placeholder and const tensor
    data operands for the operator.  The actual random data is generated separately for each test.'''
    def __init__(self):
        pass

    @staticmethod
    def tgBasic(testGen, opName, rank):
        pl, const = opName['operands']
        shape = testGen.makeShape(rank)

        shape_list = []
        for i in range(pl + const):
            shape_list.append(shape.copy())

        return shape_list

    @staticmethod
    def tgNHWC(testGen, opName, rank):
        pl, const = opName['operands']

        assert(rank == 4)

        shape = testGen.makeShape(rank)

        # Constrict the batch size?
        if testGen.args.max_batch_size:
            shape[0] = (shape[0] % testGen.args.max_batch_size) + 1

        shape_list = []
        for i in range(pl + const):
            shape_list.append(shape.copy())

        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)

        pl, const = op['operands']

        shape_list = []

        # Choose one of the inputs to broadcast
        bcast_idx = testGen.randInt(0, pl + const)
        for i in range(pl + const):
            shape_bcast = shape.copy()

            # If the chosen input, pick a random index to broadcast
            if i == bcast_idx:
                fuzz_idx = testGen.randInt(0, rank)
                shape_bcast[fuzz_idx] = 1

            shape_list.append(shape_bcast)

        return shape_list

    @staticmethod
    def tgConv2D(testGen, op, rank):
        pl, const = op['operands']

        assert(rank == 4)

        # IFM dimensions are NHWC
        ifm_shape = testGen.makeShape(rank)

        # Constrict the batch size?
        if testGen.args.max_batch_size:
            ifm_shape[0] = (ifm_shape[0] % testGen.args.max_batch_size) + 1

        # Get the filter height/width from the operator parameters
        filter_hw = op['filter']

        # Generate a random OFM depth
        ofm_depth = testGen.makeShape(1)[0]

        # The filter dimensions are OHWI
        filter_shape = np.asarray([ofm_depth, filter_hw[0], filter_hw[1], ifm_shape[3]])

        # The bias is OC
        bias_shape = np.asarray([ofm_depth])

        return [ifm_shape, filter_shape, bias_shape]

    @staticmethod
    def tgTransposeConv2D(testGen, op, rank):
        pl, const = op['operands']

        assert(rank == 4)

        # IFM dimensions are NHWC
        ifm_shape = testGen.makeShape(rank)

        # Constrict the batch size?
        if testGen.args.max_batch_size:
            ifm_shape[0] = (ifm_shape[0] % testGen.args.max_batch_size) + 1

        # Get the filter height/width from the operator parameters
        filter_hw = op['filter']

        # Generate a random OFM depth
        ofm_depth = testGen.makeShape(1)[0]

        # The filter dimensions are OHWI
        filter_shape = np.asarray([ofm_depth, filter_hw[0], filter_hw[1], ifm_shape[3]])

        return [ifm_shape, filter_shape]

    @staticmethod
    def tgDepthwiseConv2D(testGen, op, rank):
        pl, const = op['operands']

        assert(rank == 4)
        assert(pl == 1 and const == 2)

        # IFM dimensions are NHWC
        ifm_shape = testGen.makeShape(rank)

        # Constrict the batch size?
        if testGen.args.max_batch_size:
            ifm_shape[0] = (ifm_shape[0] % testGen.args.max_batch_size) + 1

        # Get the filter height/width from the operator parameters
        # Filter is KH, HW, C, M
        filter_hw = op['filter']

        # Generate a random OFM depth, but don't let it get too big because
        # the output depth is M * C
        filter_m = (testGen.makeShape(1)[0] % (testGen.args.tensor_shape_range[1] // 4)) + 1

        # The filter dimensions are HWCM
        filter_shape = np.asarray([filter_hw[0], filter_hw[1], ifm_shape[3], filter_m])

        # The bias is M * C
        bias_shape = np.asarray([ifm_shape[3] * filter_m])

        return [ifm_shape, filter_shape, bias_shape]

    @staticmethod
    def tgFullyConnected(testGen, op, rank):
        pl, const = op['operands']

        assert(rank == 2)
        assert(pl == 2 and const == 0)

        input_shape = testGen.makeShape(rank)
        filter_oc = testGen.makeShape(1)[0]
        filter_shape = np.asarray([filter_oc, input_shape[1]])

        bias_shape = np.asarray([filter_oc])

        return [input_shape, filter_shape, bias_shape]

    @staticmethod
    def tgMatmul(testGen, op, rank):
        pl, const = op['operands']

        assert(rank == 2)
        assert(pl == 2 and const == 0)

        a_shape = testGen.makeShape(rank)
        b_oc = testGen.makeShape(1)[0]
        b_shape = np.asarray([a_shape[1], b_oc])

        return [a_shape, b_shape]

class TosaArgGen:
    '''Argument generators create exhaustive or random lists of attributes for operators that take
       attributes or other parameters.  The return value is a list of (descriptive_name, [arglist])
       tuples where the descriptive_name is appended to the test name and the arglist is expanded
       as arguments to the operator build function.'''
    def __init__(self):
        pass

    @staticmethod
    def agNone(testGen, opName, shapeList, dtype):
        '''A trivial argument generator for operators that don't take any
           non-tensor arguments'''
        return [('', [])]

    @staticmethod
    def agAxis(testGen, opName, shapeList, dtype):
        '''Build the axis argument for operators that take a single axis'''
        axes = []

        shape = shapeList[0]

        for a in range(0, len(shape)):
            axes.append(('axis_{}'.format(a), [a]))
        return axes

    @staticmethod
    def agConv2D(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]
        filter_shape = shapeList[1]

        # Must be rank 4
        assert(len(ifm_shape) == 4)
        assert(len(filter_shape) == 4)

        maxStride = testGen.args.max_conv_stride
        maxPadding = testGen.args.max_conv_padding + 1
        maxDilation = testGen.args.max_conv_dilation

        # Strides, padding, dilations
        for stride in range(0, maxStride ** 2):
            for padding in range(0, (maxPadding) ** 4):
                for dilation in range(0, maxDilation ** 2):

                    s = [stride // maxStride + 1,
                         stride % maxStride + 1]
                    p = [(padding // (maxPadding * 4)) % maxPadding,
                         (padding // (maxPadding * 2)) % maxPadding,
                         (padding // (maxPadding * 1)) % maxPadding,
                         padding % maxPadding]
                    d = [ dilation // maxDilation + 1,
                          dilation % maxDilation + 1]

                    # 4 padding parameters for regular conv2d
                    arg_list.append(('st{}{}_pad{}{}{}{}_dilat{}{}'.format(s[0], s[1],
                                                                           p[0], p[1], p[2], p[3],
                                                                           d[0], d[1]),
                                     [ s, p, d ]))
        return arg_list

    @staticmethod
    def agTransposeConv2D(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]
        filter_shape = shapeList[1]

        # Must be rank 4
        assert(len(ifm_shape) == 4)
        assert(len(filter_shape) == 4)

        maxStride = testGen.args.max_conv_stride
        maxPadding = testGen.args.max_conv_padding + 1
        maxDilation = testGen.args.max_conv_dilation

        # Strides, padding, dilations
        for stride in range(0, maxStride ** 2):
            for out_padding in range(0, (maxPadding) ** 2):
                for dilation in range(0, maxDilation ** 2):

                    s = [stride // maxStride + 1,
                         stride % maxStride + 1]
                    p = [(out_padding // (maxPadding * 1)) % maxPadding,
                         out_padding % maxPadding]
                    d = [ dilation // maxDilation + 1,
                          dilation % maxDilation + 1]

                    oh = (ifm_shape[1] - filter_shape[1] - (filter_shape[1] - 1) * (d[0] - 1) + \
                          2 * p[0]) // s[0] + 1

                    ow = (ifm_shape[2] - filter_shape[2] - (filter_shape[2] - 1) * (d[1] - 1) + \
                          2 * p[1]) // s[1] + 1

                    # Output shape
                    os = [ ifm_shape[0], oh, ow, filter_shape[0] ]

                    arg_list.append(('st{}{}_outpad{}{}_dilat{}{}_os{}x{}x{}x{}'.format(s[0], s[1],
                                                                                        p[0], p[1],
                                                                                        d[0], d[1],
                                                                                        os[0], os[1], os[2], os[3]),
                                     [ s, p, d, os ]))

        return arg_list

    @staticmethod
    def agPad(testGen, opName, shapeList, dtype):
        arg_list = []
        rank = len(shapeList[0])

        # Exhaustively test combinations of 0/1 padding on each side of each dimension
        # This process might need some revision for >1 padding, but use rank**2 as a bitmask
        # for now
        for v in range(rank ** 2):

            # Create a flat arraypadding4D
            paddings = np.zeros((rank * 2), dtype=np.int32)

            # Fill in the 1's
            for r in (range(rank * 2)):
                if (v >> r) & 1:
                    paddings[r] = 1

            # Reshape back to a 2D array
            paddings = paddings.reshape((rank, 2))

            arg_list.append(('pad{0:b}'.format(v), [ paddings ]))

        return arg_list

    @staticmethod
    def agPooling(testGen, opName, shapeList, dtype):
        arg_list = []

        shape = shapeList[0]
        assert(len(shape) == 4)

        maxStride = testGen.args.max_pooling_stride
        maxKernel = testGen.args.max_pooling_kernel
        maxPadding = testGen.args.max_pooling_padding + 1

        for kernel in range(0, maxKernel ** 2):
            for stride in range(0, maxStride ** 2):
                for padding in range(0, maxPadding ** 4):
                    s = [stride // maxStride + 1,
                         stride % maxStride + 1]
                    k = [(kernel // maxKernel) + 2,
                         (kernel % maxKernel) + 2]
                    p = [(padding // (maxPadding * 4)) % maxPadding,
                         (padding // (maxPadding * 2)) % maxPadding,
                         (padding // (maxPadding * 1)) % maxPadding,
                         padding % maxPadding]

                    arg_list.append(('st{}{}_kern{}{}_pad{}{}{}{}'.format(s[0], s[1],
                                                                          k[0], k[1],
                                                                          p[0], p[1], p[2], p[3]),
                                     [k, s, p]))
        return arg_list

    @staticmethod
    def agCast(testGen, opName, shapeList, inDtype):
        arg_list = []

        # Enumerate the output types here
        if inDtype == DType.INT8:
            dtypeList = [ DType.BOOL, DType.INT16, DType.INT32, DType.FLOAT ]
        elif inDtype == DType.INT16:
            dtypeList = [ DType.BOOL, DType.INT8, DType.INT32, DType.FLOAT ]
        elif inDtype == DType.INT32:
            dtypeList = [ DType.BOOL, DType.INT8, DType.INT16, DType.FLOAT ]
        elif inDtype == DType.BOOL:
            dtypeList = [ DType.INT8, DType.INT16, DType.INT32 ]
        elif inDtype == DType.FLOAT:
            dtypeList = [ DType.INT8, DType.INT16, DType.INT32 ]
        else:
            raise Exception('Unexpected input dtype: {}'.format(inDtype))

        for dtype in dtypeList:
            arg_list.append(('out{}'.format(DTypeNames[dtype]), [dtype]))

        return arg_list

    @staticmethod
    def agRescale(testGen, opName, shapeList, inDtype):
        arg_list = []

        # Enumerate the output types here
        for dtype in [ DType.INT8, DType.INT16, DType.INT32 ]:
            for scale32 in [ False, True ]:
                for double_round in [ False, True ]:
                    for per_channel in [ False, True ]:

                        if inDtype == DType.INT48 and scale32:
                            # Illegal condition.  Must be scale32=False
                            continue

                        arg_list.append(('out{}_sc{}_dr{}_pc{}'.format(DTypeNames[dtype], int(scale32), int(double_round), int(per_channel)),
                                         [dtype, scale32, double_round, per_channel]))

        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):
        factors = []

        for i in range(start, int(np.sqrt(val))):
            if (val % i) == 0:
                factors.append(i)

        return factors

    @staticmethod
    def agReshape(testGen, opName, shapeList, dtype):
        arg_list = []

        origShape = shapeList[0]

        totalElements = 1
        for s in origShape:
            totalElements *= s

        # This code is NOT fast.  Fortunately, the numbers are fairly small.
        factors = TosaArgGen.getFactors(totalElements)

        for p in range(testGen.args.num_rand_permutations):
            newRank = testGen.randInt(1, 6)
            newShape = []
            if (len(factors) < newRank):
                continue

            remainingElements = totalElements
            shuffledFactors = testGen.rng.permutation(factors)
            for i in range(newRank):
                # pick rank-1 factors
                newShape.append(shuffledFactors[0])
                remainingElements = remainingElements // shuffledFactors[0]
                shuffledFactors = testGen.rng.permutation(TosaArgGen.getFactors(remainingElements))
            newShape.append(remainingElements)

            # Toss in a -1 sometimes
            minusOne = testGen.randInt(0, newRank * 4)
            if minusOne < newRank:
                newShape[minusOne] = -1

            arg_list.append(('perm{}_rank{}'.format(p, newRank), [newShape]))

        return arg_list


    @staticmethod
    def agTranspose(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]

        perms = range(len(ifm_shape))
        for p in range(testGen.args.num_rand_permutations):
            perms = np.int32(testGen.rng.permutation(perms)).tolist()

            # Avoid duplicates
            found = False
            for name, other_perm in arg_list:
                if other_perm[0] == perms:
                    found = True
                    break

            if not found:
                arg_list.append(('perm{}'.format(p), [perms]))

        return arg_list

    @staticmethod
    def agSlice(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]
        rank = len(ifm_shape)

        for p in range(testGen.args.num_rand_permutations):
            begin = []
            size = []

            valid=True

            for i in range(rank):
                if ifm_shape[i] > 1:
                    begin.append(testGen.randInt(0, ifm_shape[i]))
                    size.append(testGen.randInt(0, ifm_shape[i] - begin[i]))

                    # Invalid slice size?
                    if size[i] == 0:
                        valid = False
                else:
                    begin.append(0)
                    size.append(1)

            if valid:
                arg_list.append(('perm{}'.format(p), [begin, size]))
        return arg_list

    @staticmethod
    def agTile(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]
        rank = len(ifm_shape)

        for p in range(testGen.args.num_rand_permutations):

            # Pick a few random, but small multiple values
            # because otherwise this has a tendency to generate
            # enormous tensors
            multiples = []
            for i in range(rank):
                multiples.append(testGen.randInt(1, 4))

            arg_list.append(('perm{}'.format(p), [multiples]))

        return arg_list

    @staticmethod
    def agResize(testGen, opName, shapeList, dtype):
        arg_list = []

        ifm_shape = shapeList[0]

        for m in [ResizeMode.NEAREST, ResizeMode.BILINEAR]:

            # Exclude illegal {mode, type} configurations.  Pick legal output types
            if m == ResizeMode.NEAREST and dtype == DType.INT8:
                outputDTypeList = [ DType.INT32 ]
            elif m == ResizeMode.NEAREST and dtype == DType.INT16:
                outputDTypeList = [ DType.INT16 ]
            elif m == ResizeMode.BILINEAR and dtype == DType.INT8:
                outputDTypeList = [ DType.INT8 ]
            elif m == ResizeMode.BILINEAR and dtype == DType.INT16:
                outputDTypeList = [ DType.INT48 ]
            elif dtype == DType.FLOAT:
                outputDTypeList = [ DType.FLOAT ]
            else:
                continue

            for outputDType in outputDTypeList:
                for perm in range(testGen.args.num_rand_permutations):

                    # Randomly generate legal output dimensions and shift
                    # and then compute the stride and offset based on them
                    output_dims = [ testGen.randInt(1), testGen.randInt(1) ]
                    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

    def agCondIf(testGen, opName, shapeList, dtype):
        # CondIf generates the condition values here.
        # Convert to tensors in the build function, along with the
        # then and else blocks
        arg_list = []

        for c in [False, True]:
            arg_list.append(('cond{}'.format(int(c)), [ c ]))

        return arg_list

    def agWhileLoop(testGen, opName, shapeList, dtype):
        # While loop: 0 iterations, 1, more than 1
        arg_list = []

        for iter in [0, 1, 4]:
            arg_list.append(('iter{}'.format(iter), [ iter ]))

        return arg_list

class TosaTestGen:
    def __init__(self, args):
        self.args = args
        self.basePath = args.output_dir
        self.random_seed = args.random_seed
        self.ser = None
        self.rng = np.random.default_rng(self.random_seed)
        self.createDynamicOpLists()
        self.initOpListDefaults()
        self.quantGen = TosaQuantGen()
        # Force makeShape to do a specific starting shape
        self.targetted_shape = None

    def createSerializer(self, opName, testPath):
        self.testPath = os.path.join(opName, testPath)

        fullPath = os.path.join(self.basePath, self.testPath)
        os.makedirs(fullPath, exist_ok=True)
        self.ser = ts.TosaSerializer(fullPath)

    def getSerializer(self):
        return self.ser

    def serialize(self, testName):
        with open(os.path.join(self.basePath, self.testPath, '{}.tosa'.format(testName)), 'wb') as fd:
            fd.write(self.ser.serialize())

        with open(os.path.join(self.basePath, self.testPath, 'desc.json'), 'w') as fd:
            fd.write(self.ser.writeJson('{}.tosa'.format(testName)))

    def getRandTensor(self, shape, dtype):
        RAND_SHIFT_FACTOR = 0.5
        RAND_SCALE_FACTOR = 4.0

        if dtype == DType.BOOL:
            np_dt = np.bool
            return np.bool_(self.rng.choice(a=[False, True], size=shape))
        elif dtype == DType.INT4:
            return np.int32(self.rng.integers(low=-7, high=8, size=shape))
        elif dtype == DType.INT8:
            return np.int32(self.rng.integers(low=-127, high=128, size=shape))
        elif dtype == DType.INT16:
            return np.int32(self.rng.integers(low=-32768, high=32768, size=shape))
        elif dtype == DType.INT32:
            return np.int32(self.rng.integers(low=-(1 << 31), high=(1 << 31), size=shape))
        elif dtype == DType.INT48:
            return np.int64(self.rng.integers(low=-(1 << 47), high=(1 << 47), size=shape))
        elif dtype == DType.FLOAT:
            return np.float32(self.rng.random(size=shape) - RAND_SHIFT_FACTOR * RAND_SCALE_FACTOR)
        else:
            raise Exception('Unrecognized Dtype: {}'.format(dtype))

    def buildPlaceholderTensors(self, shape_list, dtype):
        placeholders = []

        for shape in shape_list:
            arr = self.getRandTensor(shape, dtype)
            placeholders.append(self.ser.addPlaceholder(shape, dtype, Usage.ACTIVATION, [], arr))

        return placeholders

    def buildConstTensors(self, shape_list, dtype):
        consts = []

        for shape in shape_list:
            arr = self.getRandTensor(shape, dtype)
            consts.append(self.ser.addConst(shape, dtype, Usage.ACTIVATION, [], arr))

        return consts

    def makeShape(self, rank):
        if self.targetted_shape:
            return np.int32(self.targetted_shape)
        return np.int32(self.rng.integers(low=self.args.tensor_shape_range[0],
                                          high=self.args.tensor_shape_range[1],
                                          size=rank))

    def setTargetShape(self, shape):
        self.targetted_shape = shape

    def randInt(self, low=0, high=256):
        return np.int32(self.rng.integers(low=low, high=high, size=1))[0]

    def getRandNumberDType(self, dtype):
        if dtype == DType.FLOAT:
            return self.rng.random()
        elif dtype == DType.BOOL:
            return self.rng.choice([False, True])
        elif dtype == DType.INT4:
            low, high = (-7, 8)
        elif dtype == DType.INT8:
            low, high = (-127, 128)
        elif dtype == DType.INT16:
            low, high = (-32768, 32768)
        elif dtype == DType.INT32:
            low, high = (-(1<<31), (1<<31))
        elif dtype == DType.INT48:
            low, high = (-(1<<47), (1<<47))
            # Special size
            return np.int64(self.rng.integers(low, high, size=1))[0]
        else:
            raise Exception('Unknown dtype: {}'.format(dtype))

        return np.int32(self.rng.integers(low, high, size=1))[0]

    def shapeStr(self, shape):

        sStr = []
        # Convert to strings
        for i in shape:
            sStr.append(str(i))

        return 'x'.join(sStr)

    def typeStr(self, t):
        if t == DType.BOOL:
            return 'b'
        elif t == DType.INT4:
            return 'i4'
        elif t == DType.INT8:
            return 'i8'
        elif t == DType.UINT8:
            return 'u8'
        elif t == DType.INT16:
            return 'i16'
        elif t == DType.INT32:
            return 'i32'
        elif t == DType.INT48:
            return 'i48'
        elif t == DType.FLOAT:
            return 'float'
        else:
            raise Exception('Unknown dtype, cannot convert to string: {}'.format(t))

    def typeWidth(self, t):
        ''' Get the datatype width for integer types'''
        if t == DType.INT4:
            return 4
        elif t == DType.INT8:
            return 8
        elif t == DType.UINT8:
            return 8
        elif t == DType.INT16:
            return 16
        elif t == DType.INT32:
            return 32
        elif t == DType.INT48:
            return 48
        else:
            raise Exception('Unknown dtype, cannot convert to string: {}'.format(t))

    # Argument generators
    # Returns a list of tuples (stringDescriptor, [build_fcn_arg_list])
    # Where the string descriptor is used to generate the test name and
    # The build_fcn_arg_list is expanded and passed to the operator test
    # build function


    def build_unary(self, op, a, qinfo = None):
        result_tens = OutputShaper.unaryOp(self.ser, a)
        self.ser.addOperator(op, [a.name], [result_tens.name], None, qinfo)
        return result_tens

    def build_binary_broadcast(self, op, a, b):
        result_tens = OutputShaper.binaryBroadcastOp(self.ser, a, b)
        self.ser.addOperator(op, [a.name, b.name], [result_tens.name])
        return result_tens

    def build_binary_nonbroadcast(self, op, a, b):
        result_tens = OutputShaper.binaryNonBroadcastOp(self.ser, a, b)
        self.ser.addOperator(op, [a.name, b.name], [result_tens.name])
        return result_tens

    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:
        # Force the result to INT32 for INT types
        if a.dtype != DType.FLOAT:
            result_tens.setDtype(DType.INT32)

        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):
        # Constant size, random values
        table_arr = self.getRandTensor([513], DType.INT16)
        table_tens = self.ser.addConst(table_arr.shape, DType.INT16, Usage.INDEX, [], table_arr)

        result_tens = OutputShaper.tableOp(self.ser, a, table_tens)
        self.ser.addOperator(op, [a.name, table_tens.name], [result_tens.name], None)

        return result_tens

    def build_select(self, op, cond, a, b):

        # Replace the cond tensor with a boolean tensor since it probably
        # has the wrong dtype
        t = self.buildPlaceholderTensors([cond.shape], DType.BOOL)
        cond = t[0]

        result_tens = OutputShaper.selectOp(self.ser, cond, a, b)
        self.ser.addOperator(op, [cond.name, a.name, b.name], [result_tens.name])

        return result_tens

    def build_comparison(self, op, a, b):
        result_tens = OutputShaper.binaryComparisonOp(self.ser, a, b)
        self.ser.addOperator(op, [a.name, b.name], [result_tens.name])
        return result_tens

    def build_argmax(self, op, a, axis):
        result_tens = OutputShaper.argmaxOp(self.ser, a, axis)

        attr = ts.TosaSerializerAttribute()
        attr.AxisAttribute(axis)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_pool2d(self, op, input, kernel, stride, pad, qinfo = None):
        result_tens = OutputShaper.pool2dOp(self.ser, input, kernel, stride, pad)

        attr = ts.TosaSerializerAttribute()
        attr.Pool2dAttribute(kernel, stride, pad)
        input.addFormat(Format.NHWC)

        self.ser.addOperator(op, [input.name], [result_tens.name], attr, qinfo)
        return result_tens

    def build_conv2d(self, op, ifm, filter, bias, strides, padding, dilations, qinfo):
        assert(len(padding) == 4)
        result_tens = OutputShaper.conv2dOp(self.ser, ifm, filter, strides, padding, dilations)

        attr = ts.TosaSerializerAttribute()
        attr.Conv2dAttribute(padding, strides, dilations)

        ifm.addFormat(Format.NHWC)
        # Update the filter ordering
        filter.addUsage(Usage.WEIGHT)
        filter.addFormat(Format.OHWI)

        self.ser.addOperator(op, [ifm.name, filter.name, bias.name], [result_tens.name], attr, qinfo)
        return result_tens

    def build_transpose_conv2d(self, op, ifm, filter, stride, outpad, dilation, output_shape, qinfo):
        assert(len(outpad) == 2)
        result_tens = OutputShaper.transposeConv2DOp(self.ser, ifm, output_shape)

        attr = ts.TosaSerializerAttribute()
        attr.TransposeConv2DAttribute(outpad, stride, dilation, output_shape)

        ifm.addFormat(Format.NHWC)
        # Update the filter ordering
        filter.addUsage(Usage.WEIGHT)
        filter.addFormat(Format.OHWI)

        # Create bias here since the acc_t depends on (but isn't the same as) the input dtype
        # The bias is OC
        if ifm.dtype == DType.INT8:
            bias_type = DType.INT32
        elif ifm.dtype == DType.INT16:
            bias_type = DType.INT48
        elif ifm.dtype == DType.FLOAT:
            bias_type = DType.FLOAT
        else:
            raise Exception('Unsupported dtype for transpose_conv2d: {}'.format(ifm.dtype))

        bias_arr = self.getRandTensor([filter.shape[0]], bias_type)
        bias_tens = self.ser.addConst([filter.shape[0]], bias_type, [], [], bias_arr)

        self.ser.addOperator(op, [ifm.name, filter.name, bias_tens.name], [result_tens.name], attr, qinfo)
        return result_tens

    def build_depthwise_conv2d(self, op, ifm, filter, bias, strides, padding, dilations, qinfo):
        result_tens = OutputShaper.depthwiseConv2dOp(self.ser, ifm, filter, strides, padding, dilations)

        attr = ts.TosaSerializerAttribute()
        attr.Conv2dAttribute(padding, strides, dilations)

        ifm.addFormat(Format.NHWC)
        filter.addUsage(Usage.WEIGHT)
        filter.addFormat(Format.HWIM)

        self.ser.addOperator(op, [ifm.name, filter.name, bias.name], [result_tens.name], attr, qinfo)
        return result_tens

    def build_fully_connected(self, op, ifm, filter, bias, qinfo):
        result_tens = OutputShaper.fullyConnectedOp(self.ser, ifm, filter)

        filter.addUsage(Usage.WEIGHT)
        self.ser.addOperator(op, [ifm.name, filter.name, bias.name], [result_tens.name], None, qinfo)
        return result_tens

    def build_matmul(self, op, a, b, qinfo):
        result_tens = OutputShaper.matmulOp(self.ser, a, b)
        self.ser.addOperator(op, [a.name, b.name], [result_tens.name], None, qinfo)
        return result_tens

    def build_reduce(self, op, a, axis):
        result_tens = OutputShaper.reduceOp(self.ser, a, axis)

        attr = ts.TosaSerializerAttribute()
        attr.AxisAttribute(axis)

        self.ser.addOperator(op, [a.name], result_tens.name, attr)
        return result_tens

    def build_clamp(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)

        attr = ts.TosaSerializerAttribute()

        # Get two random ints
        v = [self.randInt(), self.randInt()]

        if a.dtype == DType.FLOAT:
            attr.ClampAttribute(0, 0, min(v), max(v))
        else:
            attr.ClampAttribute(min(v), max(v), 0, 0)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_leaky_relu(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)
        attr = ts.TosaSerializerAttribute()

        attr.LeakyReluAttribute(self.getRandNumberDType(DType.FLOAT))

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    # Needs an additional type/input
    def build_prelu(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)

        self.ser.addOperator(op, [a.name], [result_tens.name])
        return result_tens

    def build_relun(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)

        attr = ts.TosaSerializerAttribute()

        if a.dtype == DType.FLOAT:
            attr.ReluNAttribute(0, self.getRandNumberDType(a.dtype))
        else:
            attr.ReluNAttribute(self.getRandNumberDType(a.dtype), 0)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_sigmoid(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)
        self.ser.addOperator(op, [a.name], [result_tens.name])
        return result_tens

    def build_tanh(self, op, a):
        result_tens = OutputShaper.unaryOp(self.ser, a)
        self.ser.addOperator(op, [a.name], [result_tens.name])
        return result_tens

    def build_concat(self, op, a, b, axis):
        result_tens = OutputShaper.concatOp(self.ser, a, b, axis)

        attr = ts.TosaSerializerAttribute()
        attr.AxisAttribute(axis)

        self.ser.addOperator(op, [a.name, b.name], [result_tens.name], attr)

    def build_pad(self, op, a, padding, qinfo):
        result_tens = OutputShaper.padOp(self.ser, a, padding)

        # Need to turn the padding array into a TOSA tensor here.
        # This is one of the few tensor operands that does not get
        # randomly generated
        padding_tens = self.ser.addConst(padding.shape, DType.INT32, [], [], padding)

        self.ser.addOperator(op, [a.name, padding_tens.name], [result_tens.name], None, qinfo)

    def build_reshape(self, op, a, newShape):
        result_tens = OutputShaper.reshapeOp(self.ser, a, newShape)

        attr = ts.TosaSerializerAttribute()
        attr.ReshapeAttribute(newShape)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_reverse(self, op, a, axis):
        result_tens = OutputShaper.unaryOp(self.ser, a)

        attr = ts.TosaSerializerAttribute()
        attr.AxisAttribute(axis)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_transpose(self, op, a, perms):
        result_tens = OutputShaper.transposeOp(self.ser, a, perms)

        perms_tens = self.ser.addConst([len(perms)], DType.INT32, Usage.ACTIVATION, [], np.int32(perms))

        self.ser.addOperator(op, [a.name, perms_tens.name], [result_tens.name])
        return result_tens

    def build_slice(self, op, a, begin, size):
        result_tens = OutputShaper.sliceOp(self.ser, a, begin, size)

        attr = ts.TosaSerializerAttribute()
        attr.SliceAttribute(begin, size)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens

    def build_tile(self, op, a, multiples):
        result_tens = OutputShaper.tileOp(self.ser, a, multiples)

        attr = ts.TosaSerializerAttribute()
        attr.TileAttribute(multiples)

        self.ser.addOperator(op, [a.name], [result_tens.name], attr)
        return result_tens


    def build_gather(self, op, values):

        # Create a new indicies tensor
        # here with data that doesn't exceed the dimensions of the values tensor

        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)

        self.ser.addOperator(op, [values.name, indicies.name], [result_tens.name])

        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, 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, stride_fp, offset_fp, mode)

        self.ser.addOperator(op, [input.name], [result_tens.name], attr)
        return result_tens

    def build_identityn(self, op, val, val2):

        result_tens  = OutputShaper.unaryOp(self.ser, val)
        result_tens2 = OutputShaper.unaryOp(self.ser, val2)
        self.ser.addOperator(op, [val.name, val2.name], [result_tens.name, result_tens2.name])
        return result_tens

    def build_placeholder(self, op, val):
        # Add an identity op to avoid warning in the reference model
        return self.build_unary(Op.IDENTITY, val)

    # Type Conversion
    def build_cast(self, op, val, out_dtype):
        result_tens = OutputShaper.typeConversionOp(self.ser, val, out_dtype)
        self.ser.addOperator(op, [val.name], [result_tens.name])
        return result_tens

    def build_rescale(self, op, val, out_dtype, scale32, double_round, per_channel):
        result_tens = OutputShaper.typeConversionOp(self.ser, val, out_dtype)

        if per_channel:
            nc = val.shape[-1]
        else:
            nc = 1

        in_type_width = self.typeWidth(val.dtype)
        out_type_width = self.typeWidth(out_dtype)

        if val.dtype == DType.INT8:
            input_zp = self.randInt()
            in_type_width = in_type_width + 1
        else:
            input_zp = 0

        if out_dtype == DType.INT8:
            output_zp = self.randInt()
            out_type_width = out_type_width + 1
        else:
            output_zp = 0

        # Calculate scale based on:
        # scale = a *(2^output_width)/(2^input_width))

        a = np.float32(self.rng.random(size=[nc]))
        scale_arr = a * np.float32((1 << out_type_width) / (1 << in_type_width))

        if scale32:
            pass
            # Cap the scaling at 2^15 - 1 for scale16
            scale_arr = np.clip(scale_arr, 1.0 / (1 << 31), (1 << 31) - 1)
        else:
            # Cap the scaling at 2^15 - 1 for scale16
            scale_arr = np.clip(scale_arr, 1.0 / (1 << 31), 32767.0)

        #print('{} {} -> {}'.format(out_type_width, in_type_width, scale_arr))

        multiplier_arr = np.int32(np.zeros(shape=[nc]))
        shift_arr = np.int32(np.zeros(shape=[nc]))

        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))

        attr = ts.TosaSerializerAttribute()
        attr.RescaleAttribute(input_zp,
                              output_zp,
                              multiplier_arr,
                              shift_arr,
                              scale32,
                              double_round,

                              per_channel)

        self.ser.addOperator(op, [val.name], [result_tens.name], attr)
        return result_tens

    def build_cond_if_const(self, op, then_tens, else_tens, cond):
        # For cond_if with constants, we're supplied with then/else tensors that we ignore
        # (except for the generated shap) and the condition.  Build Then/Else blocks
        # and fill them with const nodes for the body.

        # Condition tensor
        cond_tens = self.ser.addConst([], DType.BOOL, Usage.ACTIVATION, [], [cond])

        # Make then/else tensors
        out_shape = then_tens.shape
        then_arr = np.int32(self.rng.integers(0, 255, size=out_shape))
        else_arr = np.int32(self.rng.integers(0, 255, size=out_shape))

        # And the result tensor based on any of the outputs
        result_tens = self.ser.addOutput(out_shape, DType.INT32, Usage.ACTIVATION, [])

        # Create the attribute with the names of the then/else blocks
        then_block = 'THEN_BLOCK'
        else_block = 'ELSE_BLOCK'
        attr = ts.TosaSerializerAttribute()
        attr.CondIfAttribute(then_block, else_block)

        # Finally, build the op and the two blocks
        self.ser.addOperator(op, [cond_tens.name], [result_tens.name], attr)

        self.ser.startBasicBlock(then_block)
        # Build the actual then/else tensors inside their blocks
        then_tens = self.ser.addConst(out_shape, DType.INT32, Usage.ACTIVATION, [], then_arr)
        self.ser.addOutputTensor(then_tens)

        self.ser.startBasicBlock(else_block)
        else_tens = self.ser.addConst(out_shape, DType.INT32, Usage.ACTIVATION, [], else_arr)
        self.ser.addOutputTensor(else_tens)

        return result_tens

    def build_cond_if_binary(self, op, a, b, cond):
        # For cond_if with a binary op in the then/else blocks, take a and b and
        # alternately add or subtract them based on the condition

        # Condition tensor
        cond_tens = self.ser.addConst([], DType.BOOL, Usage.ACTIVATION, [], [cond])

        result_tens = self.ser.addOutput(a.shape, a.dtype, Usage.ACTIVATION, [])
        self.ser.currBasicBlock.addOutput(result_tens.name)

        # Create the attribute with the names of the then/else blocks
        then_block = 'THEN_BLOCK'
        else_block = 'ELSE_BLOCK'
        attr = ts.TosaSerializerAttribute()
        attr.CondIfAttribute(then_block, else_block)

        # Finally, build the op and the two blocks
        self.ser.addOperator(op, [cond_tens.name, a.name, b.name], [result_tens.name], attr)

        self.ser.startBasicBlock(then_block)
        self.ser.addInputTensor(a)
        self.ser.addInputTensor(b)
        then_tens = self.ser.addOutput(a.shape, a.dtype, a.usage, a.dformat)
        self.ser.addOperator(Op.ADD, [a.name, b.name], [then_tens.name])

        self.ser.startBasicBlock(else_block)
        self.ser.addInputTensor(a)
        self.ser.addInputTensor(b)
        else_tens = self.ser.addOutput(a.shape, a.dtype, a.usage, a.dformat)
        self.ser.addOperator(Op.SUB, [a.name, b.name], [else_tens.name])

        return result_tens

    def build_while_loop(self, op, a, iter_val):
        iter = self.ser.addPlaceholder([], DType.INT32, Usage.ACTIVATION, [], [np.int32(iter_val)])

        cond_block = 'COND_BLOCK'
        body_block = 'BODY_BLOCK'

        attr = ts.TosaSerializerAttribute()
        attr.WhileLoopAttribute(cond_block, body_block)

        # Accumulator tensor
        #acc = self.ser.addOutput(a.shape, a.dtype, a.usage, a.dformat)
        acc_init_val = np.int32(np.zeros(a.shape))
        acc = self.ser.addPlaceholder(a.shape, a.dtype, a.usage, a.dformat, acc_init_val)

        # Intermediate/output tensors for everything going through the loop
        iter_out = self.ser.addIntermediate(iter.shape, iter.dtype, iter.usage, iter.dformat)
        a_out    = self.ser.addIntermediate(a.shape, a.dtype, a.usage, a.dformat)
        acc_out  = self.ser.addIntermediate(acc.shape, acc.dtype, acc.usage, acc.dformat)

        # While_loop operator
        self.ser.addOperator(op,
                             [iter.name, a.name, acc.name],
                             [iter_out.name, a_out.name, acc_out.name], attr)

        # COND block (input: iter, output: cond_tens )
        self.ser.startBasicBlock(cond_block)
        self.ser.addInputTensor(iter)
        self.ser.addInputTensor(a)
        self.ser.addInputTensor(acc)
        zero_tens = self.ser.addConst([], DType.INT32, [], [], [np.int32(0)])
        cond_tens = self.ser.addOutput([], DType.BOOL, [], [])
        self.ser.addOperator(Op.GREATER, [iter.name, zero_tens.name],
                             [cond_tens.name])

        # BODY block (input: a, acc, iter, output: a, acc, iter)
        # Note that local intermediate tensors need to be declared here for the outputs
        self.ser.startBasicBlock(body_block)
        self.ser.addInputTensor(iter)
        self.ser.addInputTensor(a)
        self.ser.addInputTensor(acc)
        one_tens = self.ser.addConst([], DType.INT32, [], [], [np.int32(1)])
        iter_body_out = self.ser.addIntermediate(iter.shape, iter.dtype, iter.usage, iter.dformat)
        acc_body_out  = self.ser.addIntermediate(acc.shape, acc.dtype, acc.usage, acc.dformat)
        self.ser.addOperator(Op.ADD, [a.name, acc.name], [acc_body_out.name])
        self.ser.addOperator(Op.SUB, [iter.name, one_tens.name], [iter_body_out.name])
        self.ser.addOutputTensor(iter_body_out)
        self.ser.addOutputTensor(a)
        self.ser.addOutputTensor(acc_body_out)

        return acc_out


    def genOpTestList(self, opName, shapeFilter=[None], rankFilter=None, dtypeFilter=None):

        try:
            op = self.TOSA_OP_LIST[opName]
        except KeyError as e:
            raise Exception('Cannot find op with name {}'.format(opName))

        # Initialize a new random number generator
        self.rng = np.random.default_rng(self.random_seed)

        build_fcn, tgen_fcn, agen_fcn = op['build_fcn']

        # Generate the lists of arguments
        rmin, rmax = op['rank']

        # Test list consists of a tuple of:
        # (opName, testNameStr, dtype, shapeList, argumentsList)
        testList = []

        if not shapeFilter:
            shapeFilter = [None]

        for r in range(rmin, rmax + 1):

            # Filter out the rank?
            if rankFilter is not None and r not in rankFilter:
                continue

            for t in op['types']:

                # Filter tests based on dtype?
                if dtypeFilter is not None:
                    if t not in dtypeFilter:
                        continue

                # Create the placeholder and const tensors
                for shape in shapeFilter:
                    # A None shape chooses a random shape of a given rank

                    # Filter out by rank
                    if shape is not None and len(shape) != r:
                        continue

                    self.setTargetShape(shape)
                    shapeList = tgen_fcn(self, op, r)

                    shapeStr = self.shapeStr(shapeList[0])
                    typeStr = self.typeStr(t)

                    # Argument lists consists of tuples of the (str, []) string representation and the build function argument list
                    argList = []
                    if agen_fcn:
                        argList = agen_fcn(self, opName, shapeList, t)
                    else:
                        argList = [('', [])]

                    for argStr, args in argList:
                        if argStr:
                            testStr = '{}_{}_{}_{}'.format(opName, shapeStr, typeStr, argStr)
                        else:
                            testStr = '{}_{}_{}'.format(opName, shapeStr, typeStr)

                        testList.append((opName, testStr, t, shapeList, args))

        return testList

    def serializeTest(self, opName, testStr, dtype, shapeList, testArgs):
        try:
            op = self.TOSA_OP_LIST[opName]
        except KeyError as e:
            raise Exception('Cannot find op with name {}'.format(opName))

        # Create a serializer
        self.createSerializer(opName, testStr)

        build_fcn, tgen_fcn, agen_fcn = op['build_fcn']
        pCount, cCount = op['operands']

        try:
            qgen = op['qgen']
        except KeyError:
            qgen = None

        # Build the random tensor operands and the test
        tens = []

        # 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)
        else:
            qinfo = None

        try:
            if qinfo is not None:
                resultName = build_fcn(self, op['op'], *tens, *testArgs, qinfo)
            else:
                resultName = build_fcn(self, op['op'], *tens, *testArgs)
        except TypeError as e:
            print('build_fcn: {}\nTensors: {}\nArgs: {}\n'.format(build_fcn, tens, testArgs))
            raise e

        # Save the serialized test
        self.serialize('test')

    def createDynamicOpLists(self):

        # Dynamically create op lists for convolutions with a list of kernel sizes
        KERNELS = [ [1, 1], [2, 2], [3, 3], [5, 5], [3, 1], [1, 3] ]

        for k in KERNELS:
            testName = 'conv2d_{}x{}'.format(k[0], k[1])
            self.TOSA_OP_LIST[testName] = self.TOSA_OP_LIST['conv2d_TEMPLATE'].copy()
            self.TOSA_OP_LIST[testName]['filter'] = k
            self.TOSA_OP_LIST[testName]['template'] = False

            testName = 'depthwise_conv2d_{}x{}'.format(k[0], k[1])
            self.TOSA_OP_LIST[testName] = self.TOSA_OP_LIST['depthwise_conv2d_TEMPLATE'].copy()
            self.TOSA_OP_LIST[testName]['filter'] = k
            self.TOSA_OP_LIST[testName]['template'] = False

            testName = 'transpose_conv2d_{}x{}'.format(k[0], k[1])
            self.TOSA_OP_LIST[testName] = self.TOSA_OP_LIST['transpose_conv2d_TEMPLATE'].copy()
            self.TOSA_OP_LIST[testName]['filter'] = k
            self.TOSA_OP_LIST[testName]['template'] = False

        # Delete any templates after having created any dynamic ops
        # This is a two-pass operation because it's bad practice to delete
        # keys from dictionaries while iterating
        keyList = []
        for k in self.TOSA_OP_LIST:
            try:
                if self.TOSA_OP_LIST[k]['template'] == True:
                    keyList.append(k)
                    continue
            except KeyError:
                pass

        for k in keyList:
            del self.TOSA_OP_LIST[k]

    def initOpListDefaults(self):
        '''Fill in default fields for ops if they aren't already specified.
           Look for missing required fields (datastructure linting).'''
        for op in self.TOSA_OP_LIST:

            # Required fields
            try:
                pl, c = self.TOSA_OP_LIST[op]['operands']
            except (KeyError, ValueError, TypeError):
                raise Exception('Op {} is missing a valid operand tuple in TOSA_OP_LIST'.format(op))

            try:
                fcn, tgen, arggen = self.TOSA_OP_LIST[op]['build_fcn']
            except (KeyError, ValueError, TypeError):
                raise Exception('Op {} is missing a valid build_fcn tuple in TOSA_OP_LIST'.format(op))

            try:
                types = self.TOSA_OP_LIST[op]['types']
            except KeyError as e:
                raise Exception('Op {} is missing a valid type list in TOSA_OP_LIST'.format(op))

            try:
                opcode = self.TOSA_OP_LIST[op]['op']
            except KeyError as e:
                raise Exception('Op {} is missing the Op field in TOSA_OP_LIST'.format(op))

            # Put in default rank range, if missing
            try:
                rank = self.TOSA_OP_LIST[op]['rank']
            except KeyError:
                self.TOSA_OP_LIST[op]['rank'] = self.DEFAULT_RANK_RANGE

    # Tensor operator list
    #  'op': op name
    #  'operands': tuple of (placeholder, const) operands
    #  'rank': optional, restricts rank to tuple inclusive of (min, max),
    #    if not specified, defaults to (1, 4)
    #  'build_fcn': tuple of the function to (build_operator(), TensorGen function, ArgGen enum)
    #  'types': array of datatypes to be tested
    TYPE_FP = [ DType.FLOAT ]

    TYPE_INT = [ DType.INT8, DType.INT16, DType.INT32 ]                      # Excludes INT4
    TYPE_INT_FP = [ DType.INT8, DType.INT16, DType.INT32, DType.FLOAT ]      # Excludes INT4

    TYPE_BOOL = [ DType.BOOL ]
    TYPE_FI32 = [ DType.FLOAT, DType.INT32 ]
    TYPE_FIB = [ DType.FLOAT, DType.INT8, DType.INT16, DType.INT32, DType.BOOL ]
    TYPE_FI16 = [ DType.FLOAT, DType.INT16 ]

    TYPE_NARROW_INT_FP = [ DType.INT8, DType.INT16, DType.FLOAT ]

    DEFAULT_RANK_RANGE = (1, 4)

    TOSA_OP_LIST = {
        # Binary ops
        'add':
        { 'op':        Op.ADD,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'arithmetic_right_shift':
        { 'op':        Op.ARITHMETIC_RIGHT_SHIFT,
          'operands':  (2, 0),
          'build_fcn': (build_arithmetic_right_shift, TosaTensorGen.tgBroadcastFuzz, TosaArgGen.agArithmeticRightShift),
          'types':     TYPE_INT },

        'bitwise_and':
        { 'op':        Op.BITWISE_AND,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_INT },

        'bitwise_or':
        { 'op':        Op.BITWISE_OR,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_INT },

        'bitwise_xor':
        { 'op':        Op.BITWISE_XOR,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_INT },

        'logical_and':
        { 'op':        Op.LOGICAL_AND,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_BOOL },

        'logical_left_shift':
        { 'op':        Op.LOGICAL_LEFT_SHIFT,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_INT },

        'logical_right_shift':
        { 'op':        Op.LOGICAL_RIGHT_SHIFT,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_INT },

        'logical_or':
        { 'op':        Op.LOGICAL_OR,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_BOOL },

        'logical_xor':
        { 'op':        Op.LOGICAL_XOR,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_BOOL },

        'max':
        { 'op':        Op.MAXIMUM,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'min':
        { 'op':        Op.MINIMUM,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'mul':
        { 'op':        Op.MUL,
          'operands':  (2, 0),
          'build_fcn': (build_mul, TosaTensorGen.tgBroadcastFuzz, TosaArgGen.agMul),
          'types':     TYPE_INT_FP },

        'pow':
        { 'op':        Op.POW,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'sub':
        { 'op':        Op.SUB,
          'operands':  (2, 0),
          'build_fcn': (build_binary_broadcast, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'table':
        { 'op':        Op.TABLE,
          # Use the automatic generation functions to create the input array
          # but create the table tensor in the build function, as it may be
          # a different type from the input
          'operands':  (1, 0),
          'build_fcn': (build_table, TosaTensorGen.tgBasic, None),
          'types':     [ DType.INT16 ] },

        'argmax':
        { 'op':        Op.ARGMAX,
          'operands': (1, 0),
          'build_fcn': (build_argmax, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':      TYPE_FP },

        # Templated operator.  Filled in by createDynamicOpLists
        'conv2d_TEMPLATE':
        { 'op':       Op.CONV2D,
          'operands':  (1, 2),
          'rank':     (4, 4),
          'build_fcn': (build_conv2d, TosaTensorGen.tgConv2D, TosaArgGen.agConv2D),
          'qgen':      TosaQuantGen.qgConv,
          'types':     TYPE_FP,
          'template': True },

        # Templated operator.  Filled in by createDynamicOpLists
        'depthwise_conv2d_TEMPLATE':
        { 'op':       Op.DEPTHWISE_CONV2D,
          'operands':  (1, 2),
          'filter':   [1, 1],
          'rank':     (4, 4),
          'build_fcn': (build_depthwise_conv2d, TosaTensorGen.tgDepthwiseConv2D, TosaArgGen.agConv2D),
          'qgen':      TosaQuantGen.qgConv,
          'types':     TYPE_FP,
          'template': True },

        # Templated operator.  Filled in by createDynamicOpLists
        'transpose_conv2d_TEMPLATE':
        { 'op':       Op.TRANSPOSE_CONV2D,
          'operands':  (1, 1),
          'rank':     (4, 4),
          'build_fcn': (build_transpose_conv2d, TosaTensorGen.tgTransposeConv2D, TosaArgGen.agTransposeConv2D),
          'qgen':      TosaQuantGen.qgConv,
          'types':     TYPE_FP,
          'template': True },

        'fully_connected':
        { 'op':       Op.FULLY_CONNECTED,
          'operands': (2, 0),
          'rank':     (2, 2),
          'build_fcn': (build_fully_connected, TosaTensorGen.tgFullyConnected, None),
          'qgen':      TosaQuantGen.qgConv,
          'types':    TYPE_FP },

        'matmul':
        { 'op':       Op.MATMUL,
          'operands': (2, 0),
          'rank':     (2, 2),
          'build_fcn': (build_matmul, TosaTensorGen.tgMatmul, None),
          'qgen':      TosaQuantGen.qgMatmul,
          'types':     TYPE_NARROW_INT_FP },

        # Unary operators
        'abs':
        { 'op':        Op.ABS,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FI32 },

        'bitwise_not':
        { 'op':        Op.BITWISE_NOT,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_INT },

        'ceil':
        { 'op':        Op.CEIL,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'clz':
        { 'op':        Op.CLZ,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     [ DType.INT32 ] },

        'exp':
        { 'op':        Op.EXP,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'floor':
        { 'op':        Op.FLOOR,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'log':
        { 'op':        Op.LOG,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'floor':
        { 'op':        Op.FLOOR,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'logical_not':
        { 'op':        Op.LOGICAL_NOT,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_BOOL },

        'negate':
        { 'op':        Op.NEGATE,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'qgen':      TosaQuantGen.qgUnary,
          'types':     TYPE_INT_FP },

        'reciprocal':
        { 'op':        Op.RECIPROCAL,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'rsqrt':
        { 'op':        Op.RSQRT,
          'operands':  (1, 0),
          'build_fcn': (build_unary, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        # Ternary operators
        'select':
        { 'op':       Op.SELECT,
          'operands': (3, 0),
          'build_fcn': (build_select, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FIB },

        # Comparison operators
        'equal':
        { 'op':       Op.EQUAL,
          'operands': (2, 0),
          'build_fcn': (build_comparison, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'greater_equal':
        { 'op':       Op.GREATER_EQUAL,
          'operands': (2, 0),
          'build_fcn': (build_comparison, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        'greater':
        { 'op':       Op.GREATER,
          'operands': (2, 0),
          'build_fcn': (build_comparison, TosaTensorGen.tgBroadcastFuzz, None),
          'types':     TYPE_FI32 },

        # Pooling operators
        'avg_pool2d':
        { 'op':       Op.AVG_POOL2D,
          'operands': (1, 0),
          'rank':     (4, 4),
          'build_fcn': (build_pool2d, TosaTensorGen.tgNHWC, TosaArgGen.agPooling),
          'qgen':      TosaQuantGen.qgUnary,
          'types':     TYPE_NARROW_INT_FP },


        'max_pool2d':
        { 'op':       Op.MAX_POOL2D,
          'operands': (1, 0),
          'rank':     (4, 4),
          'build_fcn': (build_pool2d, TosaTensorGen.tgNHWC, TosaArgGen.agPooling),
          'types':     TYPE_NARROW_INT_FP },

        # Reduce operators
        'reduce_any':
        { 'op':       Op.REDUCE_ANY,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_BOOL },

        'reduce_all':
        { 'op':       Op.REDUCE_ALL,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_BOOL },

        'reduce_max':
        { 'op':       Op.REDUCE_MAX,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_INT_FP },

        'reduce_min':
        { 'op':       Op.REDUCE_MAX,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_INT_FP },

        'reduce_product':
        { 'op':       Op.REDUCE_PRODUCT,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_FP },

        'reduce_sum':
        { 'op':       Op.REDUCE_SUM,
          'operands':  (1, 0),
          'build_fcn': (build_reduce, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_FI32 },

        # Activation functions
        'clamp':
        { 'op':        Op.CLAMP,
          'operands':  (1, 0),
          'build_fcn': (build_clamp, TosaTensorGen.tgBasic, None),
          'types':     TYPE_NARROW_INT_FP },

        'relun':
        { 'op':        Op.RELUN,
          'operands':  (1, 0),
          'build_fcn': (build_relun, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FI32 },

        'sigmoid':
        { 'op':        Op.SIGMOID,
          'operands':  (1, 0),
          'build_fcn': (build_sigmoid, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        'tanh':
        { 'op':        Op.TANH,
          'operands':  (1, 0),
          'build_fcn': (build_tanh, TosaTensorGen.tgBasic, None),
          'types':     TYPE_FP },

        # Data layout operators
        'concat':
        { 'op':        Op.CONCAT,
          'operands':  (2, 0),
          'build_fcn': (build_concat, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_FIB },

        'pad':
        { 'op':        Op.PAD,
          'operands':  (1, 0),
          'build_fcn': (build_pad, TosaTensorGen.tgBasic, TosaArgGen.agPad),
          'qgen':      TosaQuantGen.qgPad,
          'types':     TYPE_FIB },

        'reshape':
        { 'op':        Op.RESHAPE,
          'operands':  (1, 0),
          'build_fcn': (build_reshape, TosaTensorGen.tgBasic, TosaArgGen.agReshape),
          'types':     TYPE_FIB },

        'reverse':
        { 'op':        Op.REVERSE,
          'operands':  (1, 0),
          'build_fcn': (build_reverse, TosaTensorGen.tgBasic, TosaArgGen.agAxis),
          'types':     TYPE_FIB },

        'slice':
        { 'op':        Op.SLICE,
          'operands':  (1, 0),
          'build_fcn': (build_slice, TosaTensorGen.tgBasic, TosaArgGen.agSlice),
          'types':     TYPE_FIB },

        'tile':
        { 'op':        Op.TILE,
          'operands':  (1, 0),
          'build_fcn': (build_tile, TosaTensorGen.tgBasic, TosaArgGen.agTile),
          'types':     TYPE_FIB },

        'transpose':
        { 'op':        Op.TRANSPOSE,
          'operands':  (1, 0),
          'rank':      (2, 4),  # Do not allow tranpose on rank=1
          'build_fcn': (build_transpose, TosaTensorGen.tgBasic, TosaArgGen.agTranspose),
          'types':     TYPE_FIB },

        # Scatter/Gather
        'gather':
        { 'op':        Op.GATHER,
          # Only specify 'values' tensor here. 'indices' is generated in op building stage
          'operands':  (1, 0),
          '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':
        { 'op':        Op.RESIZE,
          'operands':  (1, 0),
          'rank':      (4, 4),
          'build_fcn': ( build_resize, TosaTensorGen.tgNHWC, TosaArgGen.agResize),
          'types':    [ DType.INT8, DType.INT16, DType.FLOAT ] },


        # Data nodes
        'placeholder':
        { 'op':       Op.PLACEHOLDER,
          'operands': (1, 0),
          'build_fcn':  ( build_placeholder, TosaTensorGen.tgBasic, None),
          'types':  TYPE_FIB },

        'const':
        { 'op':       Op.CONST,
          'operands': (1, 0),
          'build_fcn':  ( build_placeholder, TosaTensorGen.tgBasic, None),
          'types':  TYPE_FIB },


        'identity':
        { 'op':       Op.IDENTITY,
          'operands': (1, 0),
          'build_fcn':  ( build_unary, TosaTensorGen.tgBasic, None),
          'types':  TYPE_FIB },


        'identityn':
        { 'op':       Op.IDENTITYN,
          'operands': (2, 0),
          'build_fcn':  ( build_identityn, TosaTensorGen.tgBasic, None),
          'types':  TYPE_FIB },

        # Type conversion
        'cast':
        { 'op':       Op.CAST,
          'operands': (1, 0),
          'build_fcn': ( build_cast, TosaTensorGen.tgBasic, TosaArgGen.agCast ),
          'types':    [ DType.FLOAT, DType.INT8, DType.INT16, DType.INT32, DType.BOOL ] },

        'rescale':
        { 'op':       Op.RESCALE,
          'operands': (1, 0),
          'build_fcn': ( build_rescale, TosaTensorGen.tgBasic, TosaArgGen.agRescale ),
          'types':     [ DType.INT8, DType.INT16, DType.INT32, DType.INT48 ] },

        # Custom
        # Not implemented.

        # Control flow

        # Two varients of cond_if, one that generates one of two constant tensors (no
        # inputs to the basic blocks, one output) and another that either adds or subtracts two tensors
        # (two inputs to the basic blocks, one output)
        'cond_if_const':
        { 'op':        Op.COND_IF,
          'operands':  (0, 2),
          'build_fcn': ( build_cond_if_const, TosaTensorGen.tgBasic, TosaArgGen.agCondIf ),
          'types':     [ DType.BOOL ] },

        'cond_if_binary':
        { 'op':        Op.COND_IF,
          'operands':  (2, 0),
          'build_fcn': ( build_cond_if_binary, TosaTensorGen.tgBasic, TosaArgGen.agCondIf ),
          'types':     TYPE_FI32 },

        # while_loop
        'while_loop':
        { 'op':        Op.WHILE_LOOP,
          'operands':  (0, 1),
          'build_fcn': ( build_while_loop, TosaTensorGen.tgBasic, TosaArgGen.agWhileLoop ),
          'types':     [DType.INT32] },


    }

class OutputShaper:
    # Methods in this class compute the expected output shape and datatype
    # for common classes of operations
    def __init__(self):
        pass

    # These methods return arguments that can be used for
    # creating a new output tensor
    @staticmethod
    def binaryBroadcastOp(ser, a, b):
        assert(len(a.shape) == len(b.shape))
        assert(a.dtype == b.dtype)

        shape = []
        for i in range(len(a.shape)):
            if a.shape[i] == 1:
                shape.append(b.shape[i])
            else:
                shape.append(a.shape[i])

        return ser.addOutput(shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def binaryNonBroadcastOp(ser, a, b):
        assert(len(a.shape) == len(b.shape))
        assert(a.dtype == b.dtype)

        shape = []
        for i in range(len(a.shape)):
            assert(a.shape[i] == b.shape[i])
            shape.append(a.shape[i])

        return ser.addOutput(shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def unaryOp(ser, a):
        return ser.addOutput(a.shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def selectOp(ser, cond, a, b):
        assert(len(a.shape) == len(b.shape) and len(a.shape) == len(cond.shape))
        assert(a.dtype == b.dtype)

        shape = []
        for i in range(len(a.shape)):
            shape.append(max(cond.shape[i], a.shape[i], b.shape[i]))

        return ser.addOutput(shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def binaryComparisonOp(ser, a, b):
        assert(len(a.shape) == len(b.shape))
        assert(a.dtype == b.dtype)

        # Do broadcast
        shape = []
        for i in range(len(a.shape)):
            if a.shape[i] == 1:
                shape.append(b.shape[i])
            else:
                shape.append(a.shape[i])

        # Force the output type to bool
        return ser.addOutput(shape, DType.BOOL, a.usage, a.dformat)

    @staticmethod
    def reduceOp(ser, a, axis):

        shape = a.shape.copy()

        shape[axis] = 1

        return ser.addOutput(shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def argmaxOp(ser, a, axis):
        shape = a.shape.copy()
        del shape[axis]
        return ser.addOutput(shape, DType.INT32, a.usage, a.dformat)

    @staticmethod
    def conv2dOp(ser, ifm, filter, strides, padding, dilations):

        # IFM:    NHWC
        # Filter: OHWI
        # OFM:    NHWC

        if len(padding) == 2:
            # Expand padding to 4 parameters in the case of transpose_conv2d
            # From H,W to T,B,L,R
            padding = [padding[0], padding[0], padding[1], padding[1]]

        h = (ifm.shape[1] - filter.shape[1] - (filter.shape[1] - 1) * (dilations[0] - 1) + \
             padding[0] + padding[1]) // strides[0] + 1

        w = (ifm.shape[2] - filter.shape[2] - (filter.shape[2] - 1) * (dilations[1] - 1) + \
             padding[2] + padding[3]) // strides[1] + 1

        if h <= 0 or w <= 0:
            # Invalid test parameters?
            h = 0
            w = 0
            ser.setExpectedFailure(True, 'Invalid combination of conv2d parameters')

        ofm_shape = [ifm.shape[0], h, w, filter.shape[0]]

        if ifm.dtype == DType.INT8:
            out_dtype = DType.INT32
        elif ifm.dtype == DType.INT16:
            out_dtype = DType.INT48
        elif ifm.dtype == DType.FLOAT:
            out_dtype = DType.FLOAT
        else:
            raise Exception('Unsupported input dtype: {}'.format(ifm.dtype))

        return ser.addOutput(ofm_shape, out_dtype, ifm.usage, ifm.dformat)

    @staticmethod
    def depthwiseConv2dOp(ser, ifm, filter, strides, padding, dilations):
        # IFM:    NHWC
        # Filter: HWCM
        # OFM:    NHW C*M
        h = (ifm.shape[1] - filter.shape[0] - (filter.shape[0] - 1) * (dilations[0] - 1) + \
             padding[0] + padding[1]) // strides[0] + 1

        w = (ifm.shape[2] - filter.shape[1] - (filter.shape[1] - 1) * (dilations[1] - 1) + \
             padding[2] + padding[3]) // strides[1] + 1

        if h <= 0 or w <= 0:
            # Invalid test parameters?
            h = 0
            w = 0
            ser.setExpectedFailure(True, 'Invalid combination of conv2d parameters')

        ofm_shape = [ifm.shape[0], h, w, filter.shape[2] * filter.shape[3]]

        if ifm.dtype == DType.INT8:
            out_dtype = DType.INT32
        elif ifm.dtype == DType.INT16:
            out_dtype = DType.INT48
        elif ifm.dtype == DType.FLOAT:
            out_dtype = DType.FLOAT
        else:
            raise Exception('Unsupported input dtype: {}'.format(ifm.dtype))

        return ser.addOutput(ofm_shape, out_dtype, ifm.usage, ifm.dformat)


    @staticmethod
    def pool2dOp(ser, ifm, kernel, stride, pad):
        # input: NHWC
        h = (ifm.shape[1] + pad[0] + pad[1] + stride[0] - kernel[0]) // stride[0]
        w = (ifm.shape[2] + pad[2] + pad[3] + stride[1] - kernel[1]) // stride[1]

        if h <= 0 or w <= 0:
            # Invalid test parameters?
            h = 0
            w = 0
            ser.setExpectedFailure(True, 'Invalid combination of pooling parameters')

        ofm_shape = [ifm.shape[0], h, w, ifm.shape[3]]
        return ser.addOutput(ofm_shape, ifm.dtype, ifm.usage, ifm.dformat)

    @staticmethod
    def fullyConnectedOp(ser, input, filter):
        # input: N, IC
        # filter: OC, IC
        # output: N, OC

        output_shape = [input.shape[0], filter.shape[0]]

        if input.dtype == DType.INT8:
            out_dtype = DType.INT32
        elif input.dtype == DType.INT16:
            out_dtype = DType.INT48
        elif input.dtype == DType.FLOAT:
            out_dtype = DType.FLOAT
        else:
            raise Exception('Unsupported input dtype: {}'.format(input.dtype))

        return ser.addOutput(output_shape, out_dtype, input.usage, input.dformat)

    @staticmethod
    def matmulOp(ser, a, b):
        # a: M, K
        # b: K, N
        # out: M, N

        output_shape = [a.shape[0], b.shape[1]]

        if a.dtype == DType.INT8:
            out_dtype = DType.INT32
        elif a.dtype == DType.INT16:
            out_dtype = DType.INT48
        elif a.dtype == DType.FLOAT:
            out_dtype = DType.FLOAT
        else:
            raise Exception('UNsupported input dtype for matmul: {}'.format(a.dtype))

        return ser.addOutput(output_shape, out_dtype, a.usage, a.dformat)

    @staticmethod
    def concatOp(ser, a, b, axis):

        output_shape = a.shape.copy()
        output_shape[axis] = a.shape[axis] + b.shape[axis]

        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def padOp(ser, a, padding):

        output_shape = a.shape.copy()

        for i in range(len(output_shape)):
            output_shape[i] = padding[i][0] + padding[i][1] + output_shape[i]

        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def reshapeOp(ser, a, shape):
        output_shape = shape.copy()

        totalElements = 1
        for i in a.shape:
            totalElements *= i

        # If there are any -1 elements, figure out what that dimension must be
        totalOutputElements = 1
        for i in output_shape:
            if i != -1:
                totalOutputElements *= i

        # And fill it in
        for i in range(len(output_shape)):
            if output_shape[i] == -1:
                output_shape[i] = totalElements // totalOutputElements

        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def sliceOp(ser, a, begin, size):

        output_shape = size.copy()
        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def tileOp(ser, a, multiples):

        output_shape = a.shape.copy()
        assert(len(multiples) == len(output_shape))

        for i in range(len(output_shape)):
            output_shape[i] = a.shape[i] * multiples[i]

        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    def transposeOp(ser, a, perms):
        output_shape = a.shape.copy()
        assert(len(perms) == len(output_shape))

        for i in range(len(output_shape)):
            output_shape[i] = a.shape[perms[i]]

        return ser.addOutput(output_shape, a.dtype, a.usage, a.dformat)

    @staticmethod
    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_in.dtype, values_in.usage, values_in.dformat)

    @staticmethod
    def tableOp(ser, input, table):
        # Same shape as the input, but with the type of the table.
        return ser.addOutput(input.shape, DType.INT32, input.usage, input.dformat)

    @staticmethod
    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 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:
                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')
            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')

        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')
            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')

        else:
            ser.setexpectedfailure(true, 'Invalid resize mode')

        return ser.addOutput(output_dims, output_dtype, input.usage, input.dformat)

    @staticmethod
    def typeConversionOp(ser, val, out_dtype):
        return ser.addOutput(val.shape, out_dtype, val.usage, val.dformat)

    @staticmethod
    def transposeConv2DOp(ser, ifm, output_shape):
        if ifm.dtype == DType.INT8:
            out_dtype = DType.INT32
        elif ifm.dtype == DType.INT16:
            out_dtype = DType.INT48
        elif ifm.dtype == DType.FLOAT:
            out_dtype = DType.FLOAT
        else:
            raise Exception('Unsupported input dtype: {}'.format(ifm.dtype))

        if output_shape[1] <= 0 or output_shape[2] <= 0:
            ser.setExpectedFailure(True, 'Negative output shape')

        return ser.addOutput(output_shape, out_dtype, ifm.usage, ifm.dformat)
