# Copyright (c) 2021-2024, ARM Limited.
# SPDX-License-Identifier: Apache-2.0
import itertools
import logging
import math

import generator.tosa_utils as gtu
import numpy as np
from generator.tosa_error_if import ErrorIf
from generator.tosa_error_if import TosaErrorIfArgGen
from serializer.tosa_serializer import DTypeNames
from tosa.DType import DType
from tosa.Op import Op
from tosa.ResizeMode import ResizeMode

# DTypeNames, DType, Op and ResizeMode are convenience variables to the
# flatc-generated types that should be enums, but aren't

logging.basicConfig()
logger = logging.getLogger("tosa_verif_build_tests")


class TosaQuantGen:
    """QuantizedInfo random generator helper functions.

    Specify with 'qgen': in the operator defintion.
    """

    def __init__(self):
        pass

    @staticmethod
    def getZeroPoint(rng, zeropoint, dtype, error_name=None):

        if dtype == DType.INT8:
            if zeropoint is not None:
                return min(127, max(-128, zeropoint))
            return rng.randInt(-128, 128)
        elif dtype == DType.UINT8:
            if zeropoint is not None:
                return min(255, max(0, zeropoint))
            return rng.randInt(0, 256)
        elif error_name in [
            ErrorIf.InputZeroPointNotZero,
            ErrorIf.WeightZeroPointNotZero,
            ErrorIf.OutputZeroPointNotZero,
        ]:
            zero_point = rng.randInt(-128, 128)
            if zero_point == 0:
                zero_point = 1
            return zero_point
        return 0

    @staticmethod
    def qgUnary(rng, zeropoint, op, dtype, error_name=None):
        if error_name == ErrorIf.InputZeroPointNotZero:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype, error_name),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
            ]
        elif error_name == ErrorIf.OutputZeroPointNotZero:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype, error_name),
            ]
        else:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
            ]
        return qinfo

    @staticmethod
    def qgConv(rng, zeropoint, op, dtype_or_dtypeList, error_name=None):
        if isinstance(dtype_or_dtypeList, list):
            # a list of [input, weights, accumulator] dtypes
            dtypeList = dtype_or_dtypeList
        else:
            # an int, [input, weights, accumulator] dtypes are the same
            dtypeList = [dtype_or_dtypeList] * 3

        if error_name == ErrorIf.InputZeroPointNotZero:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[0], error_name),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[1]),
            ]
        elif error_name == ErrorIf.WeightZeroPointNotZero:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[0]),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[1], error_name),
            ]
        else:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[0]),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtypeList[1]),
            ]
        return qinfo

    @staticmethod
    def qgMatmul(rng, zeropoint, op, dtype, error_name=None):
        if error_name == ErrorIf.InputZeroPointNotZero:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype, error_name),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype, error_name),
            ]
        else:
            qinfo = [
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
                TosaQuantGen.getZeroPoint(rng, zeropoint, dtype),
            ]
        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
        logger.debug(
            f"computeMultiplierAndShift: scalefp={scaleFp} scaleBits={scaleBits} m={m} mult={multiplier} shift={shift}"
        )

        # Adjust multiplier such that shift is in allowed value range.
        if shift == 0:
            multiplier = multiplier // 4
            shift = shift + 2
        elif shift == 1:
            multiplier = multiplier // 2
            shift = shift + 1
        elif shift == 63:
            multiplier = multiplier * 2
            shift = shift - 1

        assert multiplier <= (1 << scaleBits)
        assert shift >= 2 and shift <= 62

        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, rng, op, rank, error_name=None):
        pl, const = op["operands"]
        shape = testGen.makeShape(rng, rank)

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            shape = TosaErrorIfArgGen.eiRestrictDimensions(shape)

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

            # Generates an input rank mismatch for operators with more than one input
            if error_name == ErrorIf.RankMismatch:
                if rank == 1 and i != 1:
                    shape = testGen.makeShape(rng, rank + rng.choice([1, 2, 3]))
                elif i != 1:
                    shape = testGen.makeShape(rng, rank + rng.choice([-1, 1]))

        return shape_list

    @staticmethod
    def tgNHWC(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 4

        shape = testGen.makeShape(rng, rank)
        shape = testGen.constrictBatchSize(shape)

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name and error_name != ErrorIf.MaxDimExceeded:
            shape = TosaErrorIfArgGen.eiRestrictDimensions(shape)

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

        return shape_list

    @staticmethod
    def tgGather(testGen, rng, opName, rank, error_name=None):
        pl, const = opName["operands"]

        assert pl == 2
        assert const == 0
        if error_name != ErrorIf.WrongRank:
            assert rank == 3

        values_shape = testGen.makeShape(rng, rank)
        values_shape = testGen.constrictBatchSize(values_shape)

        N = values_shape[0]
        W = testGen.makeDimension(rng)
        indices_shape = [N, W]

        shape_list = [values_shape, indices_shape]
        return shape_list

    @staticmethod
    def tgScatter(testGen, rng, opName, rank, error_name=None):
        pl, const = opName["operands"]

        assert pl == 3
        assert const == 0
        if error_name != ErrorIf.WrongRank:
            assert rank == 3

        values_in_shape = testGen.makeShape(rng, rank)
        values_in_shape = testGen.constrictBatchSize(values_in_shape)

        N = values_in_shape[0]
        K = values_in_shape[1]
        C = values_in_shape[2]

        # Make sure W is not greater than K, as we can only write each output index
        # once (having a W greater than K means that you have to repeat a K index)
        W_min = min(testGen.args.tensor_shape_range[0], K)
        W_max = min(testGen.args.tensor_shape_range[1], K)
        W = rng.randInt(W_min, W_max) if W_min < W_max else W_min

        input_shape = [N, W, C]

        shape_list = []
        shape_list.append(values_in_shape)
        shape_list.append([N, W])  # indices
        shape_list.append(input_shape)

        return shape_list

    @staticmethod
    def _get_broadcast_shapes(testGen, rng, num_shapes, rank, error_name=None):
        if rank == 0:
            # No broadcasting possible for rank 0
            return [[]] * num_shapes

        shape = testGen.makeShape(rng, rank)
        shape_list = []

        # Choose any one of the inputs to broadcast
        # Note for ERRORS: Simplifies OutputShaper code if we don't change first shape
        bcast_idx = rng.randInt(0 if error_name is None else 1, num_shapes)
        fuzz_idx = rng.randInt(0, rank)

        for i in range(num_shapes):
            shape_bcast = shape.copy()

            # To test broadcasting, the chosen fuzz index dimension should not be 1
            if shape_bcast[fuzz_idx] == 1:
                shape_bcast[fuzz_idx] += 1

            # If the chosen input, pick a random index to broadcast
            if i == bcast_idx:
                if error_name == ErrorIf.RankMismatch:
                    # Add one rank to the shape (or more for rank of 1)
                    extra_ranks = rng.choice([1, 2, 3]) if rank == 1 else 1
                    shape_bcast = np.concatenate(
                        (shape_bcast, testGen.makeShape(rng, extra_ranks))
                    )
                    if rank != 1:
                        # Either keep the extra rank, or remove it
                        new_len = rng.choice([-2, len(shape_bcast)])
                        shape_bcast = shape_bcast[:new_len]
                elif error_name == ErrorIf.BroadcastShapesMismatch:
                    shape_bcast[fuzz_idx] += 2
                else:
                    shape_bcast[fuzz_idx] = 1

            shape_list.append(shape_bcast)

        return shape_list

    @staticmethod
    def tgBroadcastFuzz(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]
        num_shapes = pl + const
        return TosaTensorGen._get_broadcast_shapes(
            testGen, rng, num_shapes, rank, error_name
        )

    @staticmethod
    def tgMul(testGen, rng, op, rank, error_name=None):
        # Get broadcast shapes for the first 2 inputs as the 3rd is shift
        shape_list = TosaTensorGen._get_broadcast_shapes(
            testGen, rng, 2, rank, error_name
        )
        # Add a single dimension tensor for shift
        shape_list.append([1])
        return shape_list

    @staticmethod
    def tgConv2D(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 4

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

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(
                ifm_shape, max_dim=24, max_items=10000
            )

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

        # Generate a random OFM depth
        ofm_depth = testGen.makeDimension(rng)

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

        # The bias is OC or 1 if broadcastable
        try:
            if op["broadcastable_bias"]:
                if rng.choice([True, False]):
                    ofm_depth = 1
        except KeyError:
            pass
        bias_shape = np.asarray([ofm_depth])

        return [ifm_shape, filter_shape, bias_shape]

    @staticmethod
    def tgConv3D(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 5

        # IFM dimensions are NDHWC
        ifm_shape = testGen.makeShape(rng, rank)
        ifm_shape = testGen.constrictBatchSize(ifm_shape)

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(
                ifm_shape, max_dim=24, max_items=10000
            )

        # Get the filter depth/height/width from the operator parameters
        filter_dhw = op["filter"]

        # Generate a random OFM channel
        ofm_channel = testGen.makeDimension(rng)

        # The filter dimensions are ODHWI
        filter_shape = np.asarray(
            [ofm_channel, filter_dhw[0], filter_dhw[1], filter_dhw[2], ifm_shape[4]]
        )

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

        return [ifm_shape, filter_shape, bias_shape]

    @staticmethod
    def tgTransposeConv2D(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 4

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

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(
                ifm_shape, max_dim=24, max_items=10000
            )

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

        # Generate a random OFM depth
        ofm_depth = testGen.makeDimension(rng)

        # 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 tgDepthwiseConv2D(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 4
        assert pl == 1 and const == 2

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

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(
                ifm_shape, max_dim=24, max_items=10000
            )

        # 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.makeDimension(rng) % (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 tgFFT2d(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 3
        assert pl == 2 and const == 0

        # IFM dimensions are NHW
        ifm_shape = testGen.makeShape(rng, rank)

        # Select nearest lower power of two from input height and width
        ifm_shape[1] = 2 ** int(math.log(ifm_shape[1], 2))
        ifm_shape[2] = 2 ** int(math.log(ifm_shape[2], 2))

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(ifm_shape)

        # Generate an invalid kernel that is not a power of two
        if error_name == ErrorIf.KernelNotPowerOfTwo:
            inc_h = 2 if ifm_shape[1] == 1 else 1
            inc_w = 2 if ifm_shape[2] == 1 else 1
            inc_choices = [(inc_h, 0), (0, inc_w), (inc_h, inc_w)]
            selected_inc = rng.choice(inc_choices)
            ifm_shape[1] += selected_inc[0]
            ifm_shape[2] += selected_inc[1]

        ifm_shape = testGen.constrictBatchSize(ifm_shape)

        ifm_shapes = [ifm_shape.copy(), ifm_shape.copy()]
        if error_name == ErrorIf.FFTInputShapeMismatch:
            modify_shape = rng.choice([0, 1])
            # Only modify kernel (H, W)
            modify_dim = rng.choice([1, 2])
            ifm_shapes[modify_shape][modify_dim] *= 2

        return [ifm_shapes[0], ifm_shapes[1]]

    @staticmethod
    def tgRFFT2d(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 3
        assert pl == 1 and const == 0

        # IFM dimensions are NHW
        ifm_shape = testGen.makeShape(rng, rank)

        # Select nearest lower power of two from input height and width
        ifm_shape[1] = 2 ** int(math.log(ifm_shape[1], 2))
        ifm_shape[2] = 2 ** int(math.log(ifm_shape[2], 2))

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            ifm_shape = TosaErrorIfArgGen.eiRestrictDimensions(ifm_shape)

        # Generate an invalid kernel that is not a power of two
        if error_name == ErrorIf.KernelNotPowerOfTwo:
            # We must increment by 2 if current size is 1
            inc_h = 2 if ifm_shape[1] == 1 else 1
            inc_w = 2 if ifm_shape[2] == 1 else 1
            inc_choices = [(inc_h, 0), (0, inc_w), (inc_h, inc_w)]
            selected_inc = rng.choice(inc_choices)
            ifm_shape[1] += selected_inc[0]
            ifm_shape[2] += selected_inc[1]

        ifm_shape = testGen.constrictBatchSize(ifm_shape)

        return [ifm_shape]

    @staticmethod
    def tgFullyConnected(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 2

        input_shape = testGen.makeShape(rng, rank)

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            input_shape = TosaErrorIfArgGen.eiRestrictDimensions(input_shape)

        filter_oc = rng.integers(
            low=testGen.args.tensor_shape_range[0],
            high=testGen.args.tensor_shape_range[1],
            size=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, rng, op, rank, error_name=None):
        pl, const = op["operands"]

        if error_name != ErrorIf.WrongRank:
            assert rank == 3
        assert pl == 2 and const == 0

        a_shape = testGen.makeShape(rng, rank)

        # Constrict the overall size of the shape when creating ERROR_IF tests
        if error_name:
            a_shape = TosaErrorIfArgGen.eiRestrictDimensions(a_shape)

        # Get a random number for b_oc even if target shape is defined
        b_oc = np.int32(
            rng.integers(
                low=testGen.args.tensor_shape_range[0],
                high=testGen.args.tensor_shape_range[1],
                size=1,
            )
        )[0]
        # If N or H is large let b_oc be 1 to reduce output tensor size
        if max(a_shape) > 1000:
            b_oc = 1

        b_shape = np.asarray([a_shape[0], a_shape[2], b_oc])
        return [a_shape, b_shape]

    @staticmethod
    def tgConcat(testGen, rng, op, rank, error_name=None):
        pl, const = op["operands"]
        shape = testGen.makeShape(rng, rank)

        # Create extra tensors to concat.
        # Take into account value of pl when getting maximum number of concats
        num_tensors = rng.randInt(0, 4)
        shape_list = []
        for i in range(pl + const + num_tensors):
            if error_name == ErrorIf.ConcatInputRankMismatch and i != 0:
                remove = rng.choice([True, False])
                wrongShape = shape.copy()

                if remove and len(shape) > 1:
                    wrongShape = wrongShape[1:]
                else:
                    wrongShape = list(wrongShape)
                    wrongShape.append(rng.integers(1, 10))

                shape_list.append(wrongShape)
            else:
                shape_list.append(shape.copy())

        return shape_list

    @staticmethod
    def tgConcatConstInput(rng, shapeList, axis, error_name=None):
        if error_name in [
            ErrorIf.AxisSmallerZero,
            ErrorIf.AxisLargerRank,
            ErrorIf.ConcatInputRankMismatch,
        ]:
            return shapeList

        # Split concat shape along axis to allow for multiple const inputs
        # without making too many large tensors
        if len(shapeList) == 2 or shapeList[0][axis] < len(shapeList):
            # If axis can't be split we still need to invalidate other dimensions
            if error_name == ErrorIf.ConcatInputDimMismatch:
                for shape in shapeList[1:]:
                    # Negative test shapeLists are created individually for each test,
                    # so no need to copy the shape before altering it.
                    shape[(axis + 1) % len(shape)] += rng.integers(5, 10)
            return shapeList

        # Create copy of shape we are going to split (so we don't alter shapeList)
        shape = shapeList[0].copy()
        # Add original shape as first input
        new_shapeList = [shape.copy()]
        length_on_axis = shape[axis]
        remaining_length = length_on_axis
        for i in range(len(shapeList) - 2):
            # Calculate split on axis and remaining value
            split_shape_val = int(shape[axis] / 2)
            remaining_length = remaining_length - split_shape_val

            # Append new shape, and set remaining shape
            shape[axis] = split_shape_val
            new_shapeList.append(shape.copy())

            # invalidate dimensions
            if error_name == ErrorIf.ConcatInputDimMismatch:
                shape[(axis + 1) % len(shape)] += rng.integers(5, 10)
            else:
                shape[axis] = remaining_length

            if i == len(shapeList) - 3:
                new_shapeList.append(shape.copy())

        return new_shapeList


class TosaTensorValuesGen:
    """Tensor Value generators create the random data for each tensor in each test."""

    def __init__(self):
        pass

    class TVGInfo:
        """Enhanced tensor values information including data gen dict."""

        def __init__(self, tensorList, dataGenDict):
            self.tensorList = tensorList
            self.dataGenDict = dataGenDict

    # Default high value for random numbers
    TVG_FLOAT_HIGH_VALUE = {
        DType.FP32: (1 << 128) - (1 << (127 - 23)),
        DType.FP16: (1 << 16) - (1 << (15 - 10)),
        DType.BF16: (1 << 128) - (1 << (127 - 7)),
        DType.FP8E4M3: 448,
        DType.FP8E5M2: 57344,
    }

    # Default lowest normal values for random numbers
    TVG_FLOAT_LOW_VALUE = {
        DType.FP32: np.exp2(-126),
        DType.FP16: np.exp2(-14),
        DType.BF16: np.exp2(-126),
        DType.FP8E4M3: np.exp2(-9),
        DType.FP8E5M2: np.exp2(-16),
    }

    @staticmethod
    def _get_data_range(rng, dtype, highValueLookup, lowValueLookup=None):
        # Return a tuple of (low,high) data range values for the given data
        # type using a combination of per operator table limits, data limits
        # and user supplied ranges for FP numbers
        if dtype in highValueLookup:
            type_range = rng.dTypeRange(dtype, high_inclusive=True)
            high_val = highValueLookup[dtype]
            if lowValueLookup is not None and dtype in lowValueLookup:
                low_val = lowValueLookup[dtype]
            else:
                low_val = -high_val
            # Set the values to something that won't produce infinity whilst
            # respecting the default ranges if more/less than the low/high
            # values
            data_range = (
                max(low_val, type_range[0]),
                min(high_val, type_range[1]),
            )
            if data_range[0] > data_range[1]:
                # Invalid data range from low to high created due to user
                # constraints revert to using internal ranges as they are
                # known to work
                logger.info(
                    f"Using safe data range ({low_val} to {high_val}) instead of supplied ({type_range[0]} to {type_range[1]})"
                )
                data_range = (low_val, high_val)
            return data_range
        return None

    @staticmethod
    def tvgLazyGenDefault(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        # Variable inputs versus constants
        pCount, cCount = testGen.TOSA_OP_LIST[opName]["operands"]
        if "p_count" in argsDict:
            # Override for operators like CONCAT
            pCount = argsDict["p_count"]
            cCount = argsDict["c_count"]
        assert pCount + cCount == len(
            shapeList
        ), "Placeholders & Constant tensors must match shapes list"

        tens_ser_list = []

        if (
            error_name is not None
            or not gtu.dtypeIsSupportedByCompliance(dtypeList[0])
            or "data_gen" not in testGen.TOSA_OP_LIST[opName]
        ):
            # Fall back to internal data gen when dealing with unsupported types or ops
            data_range = argsDict["data_range"] if "data_range" in argsDict else None
            for idx, info in enumerate(zip(shapeList, dtypeList)):
                roundMode = False
                shape, dtype = info
                if "data_range_list" in argsDict:
                    data_range = argsDict["data_range_list"][idx]["range"]
                    roundMode = (
                        "round" in argsDict["data_range_list"][idx]
                        and argsDict["data_range_list"][idx]["round"] is True
                    )
                if data_range is not None and dtype not in (
                    DType.FP16,
                    DType.FP32,
                    DType.BF16,
                    DType.FP8E4M3,
                    DType.FP8E5M2,
                ):
                    # Change from inclusive to exclusive range
                    data_range = (data_range[0], data_range[1] + 1)

                # Ignore lazy data gen option and create data array using any range limits
                if "fixed_data" in argsDict and argsDict["fixed_data"][idx] is not None:
                    if dtype == DType.SHAPE:
                        arr = np.int64(argsDict["fixed_data"][idx])
                    elif dtype == DType.INT8:
                        arr = np.int8(argsDict["fixed_data"][idx])
                    elif dtype == DType.INT16:
                        arr = np.int16(argsDict["fixed_data"][idx])
                    elif dtype == DType.INT32:
                        arr = np.int32(argsDict["fixed_data"][idx])
                    else:
                        assert False, "Unsupported fixed_data type"
                else:
                    arr = rng.randTensor(shape, dtype, data_range)
                if roundMode:
                    arr = np.round(arr)
                if idx < pCount:
                    tens_ser_list.append(testGen.ser.addPlaceholder(shape, dtype, arr))
                else:
                    tens_ser_list.append(testGen.ser.addConst(shape, dtype, arr))

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

        # Create data generator meta-data
        dg_type = argsDict["dg_type"]
        tens_data = {
            "version": "0.1",
            "tensors": {},
        }
        dg_tens_meta = tens_data["tensors"]
        for idx, shape in enumerate(shapeList):

            tens_meta = {}
            if "fixed_data" in argsDict and argsDict["fixed_data"][idx] is not None:
                tens_meta["generator"] = gtu.DataGenType(
                    gtu.DataGenType.FIXED_DATA
                ).name
            else:
                tens_meta["generator"] = gtu.DataGenType(dg_type).name

            tens_meta["data_type"] = gtu.DTYPE_ATTRIBUTES[dtypeList[idx]]["json"]
            tens_meta["shape"] = [int(i) for i in shape]
            tens_meta["input_pos"] = idx
            tens_meta["op"] = gtu.getOpNameFromOpListName(opName).upper()

            if testGen.args.random_const_inputs:
                # Choose type of tensor biased by defaults
                percentage = rng.randInt(0, 100)
                variable = (idx < pCount and percentage < 70) or (
                    idx >= pCount and percentage >= 70
                )
            else:
                # Use default set up of constants versus inputs for the op
                variable = idx < pCount

            if variable:
                tens_meta["input_type"] = "VARIABLE"
            else:
                tens_meta["input_type"] = "CONSTANT"

            if dg_type == gtu.DataGenType.PSEUDO_RANDOM:
                info = {}
                if (
                    tens_meta["generator"]
                    == gtu.DataGenType(gtu.DataGenType.FIXED_DATA).name
                ):
                    info["data"] = [int(i) for i in argsDict["fixed_data"][idx]]
                    tens_meta["fixed_data_info"] = info
                else:
                    info["rng_seed"] = rng.seed

                    data_range = None
                    if "data_range_list" in argsDict:
                        data_range = argsDict["data_range_list"][idx]["range"]
                        if "round" in argsDict["data_range_list"][idx]:
                            info["round"] = argsDict["data_range_list"][idx]["round"]
                    elif "data_range" in argsDict:
                        data_range = argsDict["data_range"]

                    if data_range is None:
                        data_range = rng.dTypeRange(dtypeList[idx], high_inclusive=True)
                    info["range"] = [str(v) for v in data_range]
                    tens_meta["pseudo_random_info"] = info
            elif dg_type == gtu.DataGenType.DOT_PRODUCT:
                info = {}
                info["s"] = argsDict["s"]
                info["ks"] = int(argsDict["ks"])
                if "acc_type" in argsDict:
                    # Convert type number into JSON name
                    info["acc_type"] = gtu.DTYPE_ATTRIBUTES[argsDict["acc_type"]][
                        "json"
                    ]
                if "kernel" in argsDict:
                    info["kernel"] = [int(k) for k in argsDict["kernel"]]
                if "axis" in argsDict:
                    info["axis"] = int(argsDict["axis"])
                tens_meta["dot_product_info"] = info
            elif dg_type == gtu.DataGenType.FULL_RANGE:
                info = {}
                info["start_val"] = int(
                    rng.randInt(0, gtu.DTYPE_ATTRIBUTES[dtypeList[idx]]["fullset"])
                )
                tens_meta["full_range_info"] = info
            else:
                # TODO - other data gen type
                assert False, "TODO: support other data gen types"

            # Using the finished generate config meta data - generate the data if
            # needed and assign a tensor name from the serializer

            # Need to generate data when not lazy or for the bias tensor as we need
            # to work out if the bias data is non-zero for compliance
            if not testGen.args.lazy_data_gen or (
                idx == 2 and dg_type == gtu.DataGenType.DOT_PRODUCT
            ):
                # Give this tensor a temporary name until we get one from the serializer
                temp_name = f"placeholder_{idx}"
                dg_tens_meta[temp_name] = tens_meta
                # Create data now using the temporary name to access meta details
                data = testGen.dgl.get_tensor_data(temp_name, tens_data)
                if tens_meta["data_type"] == "SHAPE":
                    # Tensor type SHAPE and Numpy file type must be the same
                    data = np.int64(data)
                # Remove the item as we will give it the correct name later
                del dg_tens_meta[temp_name]

            if idx == 2 and dg_type == gtu.DataGenType.DOT_PRODUCT:
                # The KS value used by compliance verification is altered when the
                # bias data is non-zero
                if max(abs(data)) > 0.0:
                    argsDict["ksb"] = argsDict["ks"] + 1

            if testGen.args.lazy_data_gen:
                data = None

            if variable:
                tens = testGen.ser.addPlaceholder(shape, dtypeList[idx], data)
            else:
                tens = testGen.ser.addConst(shape, dtypeList[idx], data)

            tens_ser_list.append(tens)
            # Add the meta data to the list using the serializer tensor name
            dg_tens_meta[tens.name] = tens_meta

        return TosaTensorValuesGen.TVGInfo(tens_ser_list, tens_data)

    @staticmethod
    def tvgNegate(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        if dtypeList[0] == DType.INT32 and error_name is None:
            # Integer test
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 1 and cCount == 0
            ), "Op.NEGATE must have 1 placeholders, 0 consts"
            # Must create tensors with values within accumulator (int32) negatable
            # range
            max_val = (1 << 31) - 1
            min_val = -max_val
            arr = np.int32(
                rng.integers(low=min_val, high=(max_val + 1), size=shapeList[0])
            )
            tens_ser_list = []
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], arr)
            )
            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            # ERROR_IF or floating point test
            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    # Set the ADD/SUB data range to half the largest value to avoid infinities
    TVG_FLOAT_HIGH_VALUE_ADDSUB = {
        DType.FP32: (TVG_FLOAT_HIGH_VALUE[DType.FP32] / 2),
        DType.FP16: (TVG_FLOAT_HIGH_VALUE[DType.FP16] / 2),
        DType.BF16: (TVG_FLOAT_HIGH_VALUE[DType.BF16] / 2),
    }

    @staticmethod
    def tvgAddSub(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        if dtypeList[0] in (DType.INT32, DType.SHAPE) and error_name is None:
            # Make sure the integer operation does not cause value saturation - where
            # the number wraps due to limited number of bits to store the answer
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 2 and cCount == 0
            ), "Op.ADD / Op.SUB must have 2 placeholders, 0 consts"
            tens_ser_list = []
            add = op["op"] in (Op.ADD, Op.ADD_SHAPE)
            data_range = None  # Use default
            if op["op"] in (Op.ADD_SHAPE, Op.SUB_SHAPE):
                data_range = testGen.args.tensor_shape_range
            a_arr = rng.randTensor(shapeList[0], dtypeList[0], data_range)
            b_arr = rng.randTensor(shapeList[1], dtypeList[1], data_range)
            if add:
                res_arr = np.add(a_arr, b_arr, dtype=np.int64)
            else:
                res_arr = np.subtract(a_arr, b_arr, dtype=np.int64)

            # Work out the saturation limits
            max_i32 = (1 << 31) - 1
            min_i32 = -(1 << 31)
            max_arr = np.full(shapeList[1], max_i32)
            min_arr = np.full(shapeList[1], min_i32)

            # Find how much values exceed the maximum/minimums
            sat_max_arr = np.maximum(res_arr - max_arr, 0)
            sat_min_arr = np.minimum(res_arr - min_arr, 0)

            if not add:
                # Swap saturation values and negate values as we need to perform opposite operations
                sat_max_arr, sat_min_arr = -sat_min_arr, -sat_max_arr

            # Create new array of unsaturated values by clipping values as needed
            b_unsat_arr = b_arr
            if (sat_max_arr != 0).any():
                # Clip values that cause saturation
                b_unsat_arr = np.subtract(b_unsat_arr, sat_max_arr, dtype=np.int32)
                # Reduce axes in unsaturated tensor to match original tensor
                for axis, dim in enumerate(b_arr.shape):
                    if dim != b_unsat_arr.shape[axis]:
                        assert (
                            dim == 1
                        ), "Op.ADD / SUB dimension must be 1 or matching to be broadcastable"
                        b_unsat_arr = np.amin(b_unsat_arr, axis=axis, keepdims=True)

            if (sat_min_arr != 0).any():
                # Clip values that cause saturation
                b_unsat_arr = np.subtract(b_unsat_arr, sat_min_arr, dtype=np.int32)
                # Reduce axes in unsaturated tensor to match original tensor
                for axis, dim in enumerate(b_arr.shape):
                    if dim != b_unsat_arr.shape[axis]:
                        assert (
                            dim == 1
                        ), "Op.ADD / SUB dimension must be 1 or matching to be broadcastable"
                        b_unsat_arr = np.amax(b_unsat_arr, axis=axis, keepdims=True)

            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], a_arr)
            )
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[1], dtypeList[1], b_unsat_arr)
            )

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            # ERROR_IF or floating point test
            data_range = TosaTensorValuesGen._get_data_range(
                rng, dtypeList[0], TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_ADDSUB
            )
            if data_range:
                argsDict["data_range"] = data_range

            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    @staticmethod
    def tvgCondIfWhileLoop(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        if dtypeList[0] in (
            DType.INT32,
            DType.INT16,
            DType.INT8,
        ):
            # Limit input tensors with cond_if_binary or while_loop to stop
            # saturation of add/sub ops with int32 and keep all logical shift
            # values between 0 to 31 for int16 or int8
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            pRemain = pCount
            tens_ser_list = []
            for idx, shape in enumerate(shapeList[:]):
                if dtypeList[0] == DType.INT32:
                    arr = rng.randTensor(shapeList[idx], DType.INT16)
                else:
                    arr = np.int32(rng.integers(low=0, high=32, size=shapeList[idx]))
                if pRemain > 0:
                    tens_ser_list.append(
                        testGen.ser.addPlaceholder(shape, dtypeList[idx], arr)
                    )
                    pRemain -= 1
                else:
                    tens_ser_list.append(
                        testGen.ser.addConst(shape, dtypeList[idx], arr)
                    )

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    @staticmethod
    def tvgArithmeticRightShift(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        op = testGen.TOSA_OP_LIST[opName]
        pCount, cCount = op["operands"]
        # Force value of operand[1] to be within [0, num_bits]
        assert (
            pCount == 2 and cCount == 0
        ), "Op.ArithmeticRightShift must have 2 placeholders, 0 consts"

        tens_ser_list = []
        for idx, shape in enumerate(shapeList[:]):
            if idx == 1:
                if dtypeList[idx] == DType.INT8:
                    arr = np.int32(rng.integers(low=0, high=8, size=shape))
                elif dtypeList[idx] == DType.INT16:
                    arr = np.int32(rng.integers(low=0, high=16, size=shape))
                elif dtypeList[idx] == DType.INT32:
                    arr = np.int32(rng.integers(low=0, high=32, size=shape))
                elif error_name == ErrorIf.WrongInputType:
                    arr = np.int32(rng.integers(low=0, high=8, size=shape))
                else:
                    raise Exception("OpArithmeticRightShift: invalid input dtype")
            else:
                arr = rng.randTensor(shape, dtypeList[idx])
            tens_ser_list.append(testGen.ser.addPlaceholder(shape, dtypeList[idx], arr))

        return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

    @staticmethod
    def tvgReshape(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        dtypeList[1] = DType.SHAPE
        shapeList[1] = [len(argsDict["new_shape"])]
        # Create a new list for the pre-generated data in argsDict["fixed_data"]
        argsDict["fixed_data"] = [None, argsDict["new_shape"]]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgRescale(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        scale32 = argsDict["scale"]
        multiplier_arr = argsDict["multiplier"]
        shift_arr = argsDict["shift"]

        if scale32:
            dtypeList[1] = DType.INT32
        else:
            dtypeList[1] = DType.INT16
        shapeList[1] = [len(multiplier_arr)]
        dtypeList[2] = DType.INT8
        shapeList[2] = [len(shift_arr)]
        # Create a new list for the pre-generated data in argsDict["fixed_data"]
        argsDict["fixed_data"] = [None, multiplier_arr, shift_arr]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgPad(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        # argsDict["pad"] is 2D array, need to flatten it to get list of values
        pad_values = argsDict["pad"].flatten()
        dtypeList[1] = DType.SHAPE
        shapeList[1] = [len(pad_values)]
        # Create a new list for the pre-generated data in argsDict["fixed_data"]
        argsDict["fixed_data"] = [None, pad_values]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgSlice(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        dtypeList[1] = DType.SHAPE
        shapeList[1] = [len(argsDict["start"])]
        dtypeList[2] = DType.SHAPE
        shapeList[2] = [len(argsDict["size"])]
        # Create a new list for the pre-generated data in argsDict["fixed_data"]
        argsDict["fixed_data"] = [None, argsDict["start"], argsDict["size"]]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgTile(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        dtypeList[1] = DType.SHAPE
        shapeList[1] = [len(argsDict["multiples"])]
        argsDict["fixed_data"] = [None, argsDict["multiples"]]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgSelect(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        # Set datatype of condition tensor to boolean
        dtypeList[0] = DType.BOOL

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgIntDiv(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        if error_name is None:
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 2 and cCount == 0
            ), "Op.INTDIV must have 2 placeholders, 0 consts"

            tens_ser_list = []

            # Two invalid cases for Op.INTDIV:
            # 1. divisor == 0
            # 2. dividend == -(1<<31) and divisor == -1
            while True:
                dividend_arr = rng.randTensor(shapeList[0], dtypeList[0])
                divisor_arr = rng.randTensor(shapeList[1], dtypeList[1])

                if (divisor_arr == 0).any():
                    continue

                if (dividend_arr == -(2**31)).any() and (divisor_arr == -1).any():
                    continue

                break

            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], dividend_arr)
            )
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[1], dtypeList[1], divisor_arr)
            )

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    # Set the MUL data range to the square root of the largest value
    # to avoid infinities
    TVG_FLOAT_HIGH_VALUE_MUL = {
        DType.FP32: math.sqrt(TVG_FLOAT_HIGH_VALUE[DType.FP32]),
        DType.FP16: math.sqrt(TVG_FLOAT_HIGH_VALUE[DType.FP16]),
        DType.BF16: math.sqrt(TVG_FLOAT_HIGH_VALUE[DType.BF16]),
    }

    @staticmethod
    def tvgMul(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        if error_name is not None or dtypeList[0] in (
            DType.FP16,
            DType.BF16,
            DType.FP32,
        ):
            # ERROR_IF or floating point test
            data_range = TosaTensorValuesGen._get_data_range(
                rng, dtypeList[0], TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_MUL
            )
            if data_range:
                argsDict["data_range"] = data_range

            if dtypeList[0] != DType.SHAPE:
                # Need to supply shift tensor for MUL (not needed for MUL_SHAPE)
                dtypeList[2] = DType.INT8
                shapeList[2] = [1]
                # Create a new list for the pre-generated data in argsDict["fixed_data"]
                argsDict["fixed_data"] = [None, None, [argsDict["shift"]]]

            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )
        else:
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]

            tens_ser_list = []

            # Make sure multiply result in int32 range
            if dtypeList[0] == DType.SHAPE:
                shift = 0
            else:
                shift = argsDict["shift"]
            if dtypeList[0] == DType.INT8:
                num_bits = 8
            elif dtypeList[0] == DType.INT16:
                num_bits = 16
            elif dtypeList[0] in (DType.INT32, DType.SHAPE):
                num_bits = 32
            elif error_name == ErrorIf.WrongInputType:
                num_bits = 8
            else:
                raise Exception(
                    f"OpMul: invalid input dtype {gtu.DTYPE_ATTRIBUTES[dtypeList[0]]['str']}"
                )

            for idx, shape in enumerate(shapeList[:]):
                if dtypeList[idx] == DType.SHAPE:
                    low = testGen.args.tensor_shape_range[0]
                    high = testGen.args.tensor_shape_range[1]
                else:
                    low = -(2 ** (num_bits - 1))
                    high = (2 ** (num_bits - 1)) - 1

                a_arr = np.int32(rng.integers(low=low, high=high, size=shapeList[0]))
                b_arr = np.int32(rng.integers(low=low, high=high, size=shapeList[1]))

            i = 0
            while True:

                a_arr_64 = a_arr.astype(np.int64)
                b_arr_64 = b_arr.astype(np.int64)

                if shift > 0:
                    rounding = 1 << (shift - 1)
                    result_arr = ((a_arr_64 * b_arr_64) + rounding) >> shift
                else:
                    result_arr = a_arr_64 * b_arr_64

                if (result_arr > -(2**31)).all() and (
                    result_arr <= ((2**31) - 1)
                ).all():
                    break

                i = i + 1
                a_arr = a_arr // 2
                b_arr = b_arr // 2

            if dtypeList[0] == DType.SHAPE:
                # MUL_SHAPE with 2 inputs
                tens_ser_list.append(
                    testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], a_arr_64)
                )
                tens_ser_list.append(
                    testGen.ser.addPlaceholder(shapeList[1], dtypeList[1], b_arr_64)
                )
            else:
                # MUL with 3 inputs (3rd is shift)
                tens_ser_list.append(
                    testGen.ser.addPlaceholder(
                        shapeList[0], dtypeList[0], a_arr.astype(np.int32)
                    )
                )
                tens_ser_list.append(
                    testGen.ser.addPlaceholder(
                        shapeList[1], dtypeList[1], b_arr.astype(np.int32)
                    )
                )
                tens_ser_list.append(
                    testGen.ser.addPlaceholder([1], DType.INT8, np.int8([shift]))
                )

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

    @staticmethod
    def tvgConcat(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        count = len(shapeList) - testGen.args.num_const_inputs_concat
        if count < 1:
            count = 1
        if testGen.args.num_const_inputs_concat == 0:
            count = len(shapeList)

        op = testGen.TOSA_OP_LIST[opName]
        if op["op"] == Op.CONCAT_SHAPE:
            # Set the axis to 0
            shapeList = TosaTensorGen.tgConcatConstInput(rng, shapeList, 0, error_name)
        else:
            shapeList = TosaTensorGen.tgConcatConstInput(
                rng, shapeList, argsDict["axis"], error_name
            )

        # Override default pCount/cCount for operator
        argsDict["p_count"] = count
        argsDict["c_count"] = len(shapeList) - count

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgLogicalShift(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        op = testGen.TOSA_OP_LIST[opName]
        pCount, cCount = op["operands"]
        assert (
            pCount == 2 and cCount == 0
        ), "Op.LOGICAL_LEFT_SHIFT or Op.LOGICAL_RIGHT_SHIFT must have 2 placeholders, 0 consts"
        values_arr = rng.randTensor(shapeList[0], dtypeList[0])
        shift_arr = np.int32(rng.integers(low=0, high=32, size=shapeList[1]))
        tens_ser_list = []
        tens_ser_list.append(
            testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], values_arr)
        )
        tens_ser_list.append(
            testGen.ser.addPlaceholder(shapeList[1], dtypeList[1], shift_arr)
        )

        return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

    @staticmethod
    def tvgEqual(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        if error_name is None and not gtu.dtypeIsSupportedByCompliance(dtypeList[0]):
            # Integer
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 2 and cCount == 0
            ), "Op.EQUAL must have 2 placeholders, 0 consts"

            a_arr = rng.randTensor(shapeList[0], dtypeList[0])
            b_arr = rng.randTensor(shapeList[1], dtypeList[1])

            # Using random numbers means that it will be very unlikely that
            # there are any matching (equal) values, therefore force that
            # there are twice the number of matching values as the tensor rank
            for num in range(0, len(shapeList[0]) * 2):
                a_index = []
                b_index = []
                # Choose an index in each axis for the whole shape
                for axis in range(0, len(shapeList[0])):
                    # Index can be up to the largest dimension in both shapes
                    index = np.int32(
                        rng.integers(0, max(shapeList[0][axis], shapeList[1][axis]))
                    )
                    # Reduce the index down to a shape's dim for broadcasting
                    a_index.append(min(shapeList[0][axis] - 1, index))
                    b_index.append(min(shapeList[1][axis] - 1, index))

                a_arr[tuple(a_index)] = b_arr[tuple(b_index)]

            tens_ser_list = []
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[0], dtypeList[0], a_arr)
            )
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[1], dtypeList[1], b_arr)
            )
            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            # ERROR_IF or floating point test
            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    @staticmethod
    def tvgReduceSum(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        dtype = dtypeList[0]
        if dtype == DType.INT32:
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 1 and cCount == 0
            ), "Op.REDUCE_SUM must have 1 placeholders, 0 consts"
            # Limit values so that the sum cannot exceed the range of an int32 during
            # summation of any axis
            range_val = int((1 << 31) / max(shapeList[0]))
            values_arr = np.int32(
                rng.integers(low=-range_val, high=range_val, size=shapeList[0])
            )
            tens_ser_list = []
            tens_ser_list.append(
                testGen.ser.addPlaceholder(shapeList[0], dtype, values_arr)
            )
            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)
        else:
            # ERROR_IF or dot product floating point test
            if (
                error_name is None
                and argsDict["dg_type"] != gtu.ComplianceMode.DOT_PRODUCT
            ):
                # Limit ranges for (non error & non compliance) tests by using
                # values that can be summed on any axis to not hit infinity
                highval_lookup = {
                    dtype: TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE[dtype]
                    / max(shapeList[0])
                }
                data_range = TosaTensorValuesGen._get_data_range(
                    rng, dtype, highval_lookup
                )
                assert data_range is not None
                argsDict["data_range"] = data_range

            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    @staticmethod
    def tvgReduceProduct(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        dtype = dtypeList[0]
        if error_name is None:
            # Limit ranges for (non error) tests by using
            # values that can be multiplied on any axis to not hit infinity
            highval_lookup = {
                dtype: math.pow(
                    TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE[dtype],
                    1 / max(shapeList[0]),
                )
            }
            data_range = TosaTensorValuesGen._get_data_range(rng, dtype, highval_lookup)
            assert data_range is not None
            argsDict["data_range"] = data_range

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgResize(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        data_range = TosaTensorValuesGen._get_data_range(
            rng,
            dtypeList[0],
            TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE,
        )
        if data_range:
            argsDict["data_range"] = data_range
            # Needed for compliance
            argsDict["max_abs_value"] = data_range[1]

        scale_values = argsDict["scale"]
        offset_values = argsDict["offset"]
        border_values = argsDict["border"]
        dtypeList[1] = DType.SHAPE
        dtypeList[2] = DType.SHAPE
        dtypeList[3] = DType.SHAPE
        shapeList[1] = [len(scale_values)]
        shapeList[2] = [len(offset_values)]
        shapeList[3] = [len(border_values)]
        argsDict["fixed_data"] = [None, scale_values, offset_values, border_values]

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    # Set the POW exponent high data range
    TVG_FLOAT_HIGH_VALUE_POW_EXP = {
        DType.FP32: 10.0,
        DType.FP16: 10.0,
        DType.BF16: 10.0,
    }
    # POW highest base value (within a safe margin of error) that can be raised
    # to +ve exponent that doesn't become Infinity
    TVG_FLOAT_HIGH_VALUE_POW_BASE = {
        DType.FP32: math.floor(
            math.pow(
                TVG_FLOAT_HIGH_VALUE[DType.FP32],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.FP32],
            )
        ),
        DType.FP16: math.floor(
            math.pow(
                TVG_FLOAT_HIGH_VALUE[DType.FP16],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.FP16],
            )
        ),
        DType.BF16: math.floor(
            math.pow(
                TVG_FLOAT_HIGH_VALUE[DType.BF16],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.BF16],
            )
        ),
    }
    # POW lowest base value (within a safe margin of error) that can be raised
    # to -ve exponent that doesn't become Infinity
    TVG_FLOAT_LOW_VALUE_POW_BASE = {
        DType.FP32: math.ceil(
            math.pow(
                1.0 / TVG_FLOAT_HIGH_VALUE[DType.FP32],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.FP32],
            )
            * 1000
        )
        / 1000,
        DType.FP16: math.ceil(
            math.pow(
                1.0 / TVG_FLOAT_HIGH_VALUE[DType.FP16],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.FP16],
            )
            * 1000
        )
        / 1000,
        DType.BF16: math.ceil(
            math.pow(
                1.0 / TVG_FLOAT_HIGH_VALUE[DType.BF16],
                1.0 / TVG_FLOAT_HIGH_VALUE_POW_EXP[DType.BF16],
            )
            * 1000
        )
        / 1000,
    }

    @staticmethod
    def tvgPow(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        if error_name is not None:
            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )
        dtype = dtypeList[0]
        # Different ranges for POW
        test_set = argsDict["s"]
        if test_set == 0:
            # Positive base with fractional exponent
            base_range = TosaTensorValuesGen._get_data_range(
                rng,
                dtype,
                TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_POW_BASE,
                TosaTensorValuesGen.TVG_FLOAT_LOW_VALUE_POW_BASE,
            )
            exp_range = TosaTensorValuesGen._get_data_range(
                rng, dtype, TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_POW_EXP
            )
            exp_round = False
        else:
            # Integer exponent
            exp_range = TosaTensorValuesGen._get_data_range(
                rng, dtype, TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_POW_EXP
            )
            exp_round = True
            if test_set == 1:
                # Positive base
                base_range = TosaTensorValuesGen._get_data_range(
                    rng,
                    dtype,
                    TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_POW_BASE,
                    TosaTensorValuesGen.TVG_FLOAT_LOW_VALUE_POW_BASE,
                )
            else:
                assert test_set == 2
                # Negative base
                # Supply new look up tables with negative values
                base_range = TosaTensorValuesGen._get_data_range(
                    rng,
                    dtype,
                    {dtype: -TosaTensorValuesGen.TVG_FLOAT_LOW_VALUE_POW_BASE[dtype]},
                    {dtype: -TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_POW_BASE[dtype]},
                )

        data_range_list = (
            {
                "range": base_range,
            },
            {
                "range": exp_range,
                "round": exp_round,
            },
        )
        argsDict["data_range_list"] = data_range_list
        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgLogRsqrt(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        # LOG & RSQRT data range from lowest expressible positive number to
        # largest to avoid NaNs
        data_range = TosaTensorValuesGen._get_data_range(
            rng,
            dtypeList[0],
            TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE,
            TosaTensorValuesGen.TVG_FLOAT_LOW_VALUE,
        )
        if data_range:
            argsDict["data_range"] = data_range

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    # Set the EXP data range to the log of the largest to smallest values
    # to avoid infinities or making the result zero
    TVG_FLOAT_HIGH_VALUE_EXP = {
        DType.FP32: math.log(TVG_FLOAT_HIGH_VALUE[DType.FP32]),
        DType.FP16: math.log(TVG_FLOAT_HIGH_VALUE[DType.FP16]),
        DType.BF16: math.log(TVG_FLOAT_HIGH_VALUE[DType.BF16]),
    }
    TVG_FLOAT_LOW_VALUE_EXP = {
        DType.FP32: math.log(TVG_FLOAT_LOW_VALUE[DType.FP32]),
        DType.FP16: math.log(TVG_FLOAT_LOW_VALUE[DType.FP16]),
        DType.BF16: math.log(TVG_FLOAT_LOW_VALUE[DType.BF16]),
    }

    @staticmethod
    def tvgExp(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        data_range = TosaTensorValuesGen._get_data_range(
            rng,
            dtypeList[0],
            TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE_EXP,
            TosaTensorValuesGen.TVG_FLOAT_LOW_VALUE_EXP,
        )
        if data_range:
            argsDict["data_range"] = data_range

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgFullyConnected(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        dtype = dtypeList[0]
        if (
            error_name is None
            and argsDict["dg_type"] != gtu.ComplianceMode.DOT_PRODUCT
            and dtype in (DType.BF16,)
        ):
            # TODO - Remove once BF16 enabled for DOT_PRODUCT compliance
            # Limit ranges for (non error & non compliance) FP tests by using
            # values that can be multiplied on any axis to not hit infinity/NaN
            IC = shapeList[0][1]
            highval_lookup = {
                dtype: math.pow(TosaTensorValuesGen.TVG_FLOAT_HIGH_VALUE[dtype], 1 / IC)
            }
            data_range = TosaTensorValuesGen._get_data_range(rng, dtype, highval_lookup)
            assert data_range is not None
            argsDict["data_range"] = data_range

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgCast(testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None):
        in_dtype = dtypeList[0]
        out_dtype = argsDict["out_type"]
        # Create look up to limit input tensor to output type maximums to avoid
        # FP infinities and saturation of integers
        out_range = rng.dTypeRange(out_dtype, high_inclusive=True)
        highval_lookup = {in_dtype: out_range[1]}
        data_range = TosaTensorValuesGen._get_data_range(
            rng,
            in_dtype,
            highval_lookup,
        )

        assert data_range is not None
        argsDict["data_range"] = data_range

        return TosaTensorValuesGen.tvgLazyGenDefault(
            testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
        )

    @staticmethod
    def tvgGather(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        K = shapeList[0][1]

        # Fix the type of the indices tensor
        dtypeList[1] = DType.INT32

        dtype = dtypeList[0]
        if not gtu.dtypeIsSupportedByCompliance(dtype):
            # Test unsupported by data generator
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 2 and cCount == 0
            ), "Op.GATHER must have 2 placeholders, 0 consts"

            tens_ser_list = []
            for idx, shape in enumerate(shapeList):
                dtype = dtypeList[idx]
                if idx != 1:
                    arr = rng.randTensor(shape, dtype)
                    tens_ser_list.append(testGen.ser.addPlaceholder(shape, dtype, arr))
                else:
                    # Limit data range of indices tensor upto K (exclusive)
                    arr = rng.randTensor(shape, dtype, (0, K))
                    # To match old functionality - create indices as CONST
                    tens_ser_list.append(testGen.ser.addConst(shape, dtype, arr))

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

        else:
            # ERROR_IF or floating point test
            # Use inclusive values upto index K for indices tensor
            data_range_list = (
                {"range": None},
                {"range": (0, K - 1)},
            )
            argsDict["data_range_list"] = data_range_list

            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )

    @staticmethod
    def tvgScatter(
        testGen, rng, opName, dtypeList, shapeList, argsDict, error_name=None
    ):
        K = shapeList[0][1]
        W = shapeList[2][1]

        # Work out an indices tensor here with data that doesn't exceed the
        # dimension K of the values_in tensor and does NOT repeat the same K
        # location as needed by the spec:
        # "It is not permitted to repeat the same output index within a single
        # SCATTER operation and so each output index occurs at most once."
        assert K >= W, "Op.SCATTER W must be smaller or equal to K"

        # Fix the type of the indices tensor
        dtypeList[1] = DType.INT32

        dtype = dtypeList[0]
        if not gtu.dtypeIsSupportedByCompliance(dtype):
            # Test unsupported by data generator
            op = testGen.TOSA_OP_LIST[opName]
            pCount, cCount = op["operands"]
            assert (
                pCount == 3 and cCount == 0
            ), "Op.SCATTER must have 3 placeholders, 0 consts"

            tens_ser_list = []
            for idx, shape in enumerate(shapeList):
                dtype = dtypeList[idx]
                if idx != 1:
                    arr = rng.randTensor(shape, dtype)
                    tens_ser_list.append(testGen.ser.addPlaceholder(shape, dtype, arr))
                else:
                    # Create the indices array
                    assert dtype == DType.INT32, "Op.SCATTER unexpected indices type"
                    arr = []
                    for n in range(shape[0]):
                        # Get a shuffled list of output indices (0 to K-1) and
                        # limit length to W
                        arr.append(rng.permutation(K)[:W])
                    indices_arr = np.array(arr, dtype=np.int32)  # (N, W)
                    # To match old functionality - create indices as CONST
                    tens_ser_list.append(
                        testGen.ser.addConst(shape, dtype, indices_arr)
                    )

            return TosaTensorValuesGen.TVGInfo(tens_ser_list, None)

        else:
            # ERROR_IF or floating point test
            # Use inclusive values upto index K for indices tensor
            data_range_list = (
                {"range": None},
                {"range": (0, K - 1)},
                {"range": None},
            )
            argsDict["data_range_list"] = data_range_list

            return TosaTensorValuesGen.tvgLazyGenDefault(
                testGen, rng, opName, dtypeList, shapeList, argsDict, error_name
            )


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 _add_data_generators(testGen, opName, shapeList, dtype, arg_list, error_name):
        """Add extra tests for each type of data generator for this op."""
        if (
            error_name is None
            and "data_gen" in testGen.TOSA_OP_LIST[opName]
            and gtu.dtypeIsSupportedByCompliance(dtype)
        ):
            dataGenTypesList = testGen.TOSA_OP_LIST[opName]["data_gen"].get(
                dtype, (gtu.DataGenType.PSEUDO_RANDOM,)
            )

        else:
            # Error test or No data generator types listed - assume random
            dataGenTypesList = (gtu.DataGenType.PSEUDO_RANDOM,)

        # Expand arg list with other data generator types
        new_arg_list = []
        for dg_type in dataGenTypesList:
            for arg_str, args_dict in arg_list:
                gen_args_dict = args_dict.copy()
                if dg_type == gtu.DataGenType.PSEUDO_RANDOM:
                    if error_name is None:
                        num_test_sets = (
                            args_dict["num_test_sets"]
                            if "num_test_sets" in args_dict
                            else 0
                        )
                    else:
                        # Add single test for pseudo random
                        num_test_sets = 0

                elif dg_type == gtu.DataGenType.DOT_PRODUCT:
                    # Extra tests for each dot product test set
                    dot_products = args_dict["dot_products"]
                    if dot_products < testGen.TOSA_MI_DOT_PRODUCT_MIN:
                        shape_info = (
                            " ({})".format(testGen.shapeStr(args_dict["shape"]))
                            if "shape" in args_dict
                            else ""
                        )
                        logger.info(
                            f"Skipping {opName}{shape_info} {gtu.DTYPE_ATTRIBUTES[dtype]['json']} dot product test as too few calculations {dot_products} < {testGen.TOSA_MI_DOT_PRODUCT_MIN}"
                        )
                        continue
                    # KS and acc_type is required by all dot product generators
                    assert "ks" in args_dict
                    assert "acc_type" in args_dict

                    num_test_sets = testGen.TOSA_MI_DOT_PRODUCT_TEST_SETS

                elif dg_type == gtu.DataGenType.FULL_RANGE:
                    tensor_size = gtu.product(shapeList[0])
                    if tensor_size < gtu.DTYPE_ATTRIBUTES[dtype]["fullset"]:
                        shape_info = " ({})".format(shapeList[0])
                        logger.info(
                            f"Skipping {opName}{shape_info} as tensor data size too small for full range of values {tensor_size} < {gtu.DTYPE_ATTRIBUTES[dtype]['fullset']}"
                        )
                        continue
                    # Large enough tensor data size for full range, add a single test
                    num_test_sets = 0
                    arg_str = f"{arg_str}_full" if arg_str else "full"
                    gen_args_dict["tags"] = args_dict.get("tags", []) + [
                        "non_finite_fp_data"
                    ]

                gen_args_dict["dg_type"] = dg_type
                if num_test_sets > 0:
                    for s in range(0, num_test_sets):
                        set_arg_str = f"{arg_str}_s{s}" if arg_str else f"s{s}"
                        set_args_dict = gen_args_dict.copy()
                        set_args_dict["s"] = s
                        new_arg_list.append((set_arg_str, set_args_dict))
                else:
                    # Default is a single test
                    new_arg_list.append((arg_str, gen_args_dict))

        return new_arg_list

    @staticmethod
    def agNone(testGen, rng, opName, shapeList, dtype, error_name=None):
        """A trivial argument generator for operators that don't take any
        non-tensor arguments"""
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            [("", {})],
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agPow(testGen, rng, opName, shapeList, dtype, error_name=None):
        """Pow operator needs different test sets to cover random numbers
        without creating NaNs or Infs"""
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            [("", {"num_test_sets": 3})],
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agAxis(testGen, rng, opName, shapeList, dtype, error_name=None):
        """Build the axis argument for operators that take a single axis"""
        arg_list = []
        shape = shapeList[0]

        if error_name == ErrorIf.AxisSmallerZero:
            # Set too small axis
            axes = [rng.integers(-5, 0)]
        elif error_name == ErrorIf.AxisLargerRank:
            # Set too large axis
            axes = [rng.integers(len(shape) + 1, len(shape) + 10)]
        else:
            # Create tests for each dimension
            axes = range(0, len(shape))

        opid = testGen.TOSA_OP_LIST[opName]["op"]

        for a in axes:
            args_dict = {"axis": int(a)}
            if opid == Op.REDUCE_SUM:
                output_shape = shape.copy()
                if error_name is None:
                    # It only matters that we calculate the dot_products correctly
                    # for non error_if tests as they should never be run
                    output_shape[a] = 1
                args_dict["dot_products"] = gtu.product(output_shape)
                args_dict["shape"] = shape
                args_dict["ks"] = int(shape[a]) if a >= 0 and a < len(shape) else 1
                args_dict["acc_type"] = dtype if dtype != DType.BF16 else DType.FP32

            arg_list.append(("axis{}".format(a), args_dict))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def _calculate_sparsity(num_tests, sparsity_factor):
        sparsity = num_tests // sparsity_factor + 1
        # If there are only a small number of tests, just select them all
        if sparsity < 13:
            sparsity = 1
        # To get a variety of parameter combinations sparsity should not be a
        # multiple of 2, 3 or 5
        while sparsity % 2 == 0 or sparsity % 3 == 0 or sparsity % 5 == 0:
            sparsity += 1
        return sparsity

    # Maximum number of error_if variants to produce
    MAX_TESTS_ERROR_IFS = 3

    @staticmethod
    def agConv(testGen, rng, opName, shapeList, dtypes, error_name=None):
        # Used by CONV2D, CONV3D and DEPTHWISE_CONV2D
        arg_list = []

        # Shape: Batches, (Depth), Height, Width, Channels
        ifm_shape = shapeList[0]
        # Shape: (OFM channels), (KD), KH, KW, IFM channels
        filter_shape = shapeList[1]

        accum_dtypes = gtu.get_accum_dtypes_from_tgTypes(dtypes)

        if error_name == ErrorIf.WrongAccumulatorType:
            accum_dtypes = (
                [DType.BF16] if gtu.dtypeIsFloat(dtypes[0]) else [DType.INT16]
            )

        # For op type checks
        op = testGen.TOSA_OP_LIST[opName]

        # Check the rank
        rank = 5 if op["op"] == Op.CONV3D else 4
        if error_name != ErrorIf.WrongRank:
            assert len(ifm_shape) == rank
            assert len(filter_shape) == rank

        # kernel rank omits channels
        k_rank = rank - 2
        k_pos = 0 if op["op"] == Op.DEPTHWISE_CONV2D else 1
        k_shape = tuple(filter_shape[k_pos : (k_pos + k_rank)])
        # compliance size - KS
        k_size = gtu.product(k_shape)
        if not op["op"] == Op.DEPTHWISE_CONV2D:
            k_size *= ifm_shape[-1]

        def get_conv_output_info(p, s, d, fix_up_padding=False):
            # Work out remainders and output dimensions with an
            # option to adjust paddings to create a valid operation
            nonlocal ifm_shape, k_shape, error_name, k_rank
            if fix_up_padding:
                p = list(p)  # Make paddings editable
            outputs_no_stride = []
            remainders = []
            outputs = []
            for index in range(k_rank):
                pad_offset = index * 2
                fixed = False
                # Fix up pad values to produce valid conv2d
                while not fixed:
                    # Output dimension without being adjusted for stride
                    output_no_stride = (
                        ifm_shape[index + 1]
                        - 1
                        + p[pad_offset]
                        + p[pad_offset + 1]
                        - (k_shape[index] - 1) * d[index]
                    )
                    # Tensor left over after applying striding
                    remainder = output_no_stride % s[index]
                    if not fix_up_padding:
                        # Just want remainders and outputs
                        break
                    if output_no_stride <= 0:
                        p[pad_offset + 1] += abs(output_no_stride) + 1
                        continue
                    if error_name == ErrorIf.ConvOutputShapeNonInteger:
                        if remainder:
                            # Conditions to trigger the test
                            fixed = True
                        else:
                            p[pad_offset + 1] += 1
                    else:
                        if remainder:
                            # Stride will be negative for StrideSmallerOne
                            assert remainder > 0 or (
                                error_name == ErrorIf.StrideSmallerOne and remainder < 0
                            )
                            p[pad_offset + 1] += abs(remainder)
                        else:
                            fixed = True
                outputs_no_stride.append(output_no_stride)
                remainders.append(remainder)
                # Output dimension taking in to account stride
                outputs.append((output_no_stride // s[index]) + 1)

            if fix_up_padding:
                p = tuple(p)  # Make the paddings read-only
                assert min(outputs_no_stride) > 0, "Fix up did not work!"
            return p, remainders, outputs, outputs_no_stride

        # Only fix up padding for conv2d and float types currently
        fix_up_padding = gtu.dtypeIsFloat(dtypes[0]) and op["op"] == Op.CONV2D
        # Allow any size of output dimension
        max_dim_size = None
        # Include all tests by default
        sparsity = 1

        # Work out padding, strides and dilation ranges depending on
        # error and arguments
        if error_name in (
            ErrorIf.PadSmallerZero,
            ErrorIf.StrideSmallerOne,
            ErrorIf.DilationSmallerOne,
        ):
            # Use specific invalid value(s)
            if error_name == ErrorIf.PadSmallerZero:
                # Create negative paddings but with positive opposite paddings
                neg_pad = rng.choice(range(-5, 0))
                p_vals = [neg_pad, abs(neg_pad)]
            else:
                p_vals = [0, 0]
            if error_name == ErrorIf.StrideSmallerOne:
                # Can't use stride=0, as it is used to derive output shape, as a divisor
                s_vals = [rng.choice(range(-5, 0))]
            else:
                s_vals = [1]
            if error_name == ErrorIf.DilationSmallerOne:
                d_vals = [rng.choice(range(-5, 1))]
            else:
                d_vals = [1]
            paddings = {tuple(p_vals) * k_rank}
            strides = {tuple(s_vals) * k_rank}
            dilations = {tuple(d_vals) * k_rank}

            fix_up_padding = True  # Need to fix up paddings to be valid

        elif testGen.args.level8k and error_name is None:
            # Only test 8k levels boundaries
            bigStride = testGen.TOSA_8K_LEVEL_MAX_STRIDE
            bigKernel = testGen.TOSA_8K_LEVEL_MAX_KERNEL
            bigPadding = bigKernel

            dilation_shape = [1] * k_rank
            pad_shape = [0] * k_rank * 2
            if op["op"] == Op.CONV3D:
                # Small stride apart from for big kernel (see below) to keep
                # tensor size/calculation small
                stride_shape = [1] * k_rank
                for idx in range(k_rank):
                    pad_offset = idx * 2
                    if k_shape[idx] == bigKernel:
                        # Padding shape needs to account for tensor shape
                        pad_shape[pad_offset] = bigPadding - ifm_shape[idx + 1]
                        pad_shape[pad_offset + 1] = bigPadding - dilation_shape[idx] + 1
                        # Big stride to reduce output size
                        stride_shape[idx] = bigKernel
                    else:
                        # Account for kernel size
                        pad_shape[pad_offset] = k_shape[idx] - 1
            else:
                # Always have a large stride with extra padding and dilation to keep
                # tensor calculation reasonable
                stride_shape = [bigKernel] * k_rank
                for idx in range(k_rank):
                    # Dilation shape must account for kernel size
                    dilation_shape[idx] = bigKernel // k_shape[idx]
                    # Padding shape needs to accommodate tensor/kernel & dilation
                    pad_offset = idx * 2
                    pad_shape[pad_offset] = bigPadding - ifm_shape[idx + 1]
                    pad_shape[pad_offset + 1] = bigPadding - dilation_shape[idx] + 1

            strides = {tuple(stride_shape)}
            dilations = {tuple(dilation_shape)}
            paddings = {tuple(pad_shape)}
            # Create a limit for the output dimensions size
            max_dim_size = testGen.TOSA_8K_LEVEL_MAX_KERNEL

            # Currently allow all combinations that are reasonable size
            sparsity = 1
        else:
            # Generate comprehensive argument lists
            p_vals = [x for x in range(0, testGen.args.max_conv_padding + 1)]
            paddings = {x for x in itertools.product(*([p_vals] * k_rank * 2))}
            # Stride must be greater than 1 to force non-integer error
            startStride = 1 if error_name != ErrorIf.ConvOutputShapeNonInteger else 2
            s_vals = [x for x in range(startStride, testGen.args.max_conv_stride + 1)]
            d_vals = [x for x in range(1, testGen.args.max_conv_dilation + 1)]

            strides = {x for x in itertools.product(*([s_vals] * k_rank))}
            dilations = {x for x in itertools.product(*([d_vals] * k_rank))}

            if error_name is None and testGen.args.oversize:
                # add some oversize argument values
                if max(ifm_shape) < 64:
                    bigPadding = 9
                    paddings.update(
                        {
                            x
                            for x in itertools.product(
                                *([[0, bigPadding]] * (k_rank * 2))
                            )
                        }
                    )
                bigStride = 8
                strides.update(
                    {x for x in itertools.product(*([[1, bigStride]] * k_rank))}
                )
                bigDilation = 7
                dilations.update(
                    {x for x in itertools.product(*([[1, bigDilation]] * k_rank))}
                )

            if error_name is None:
                # There are too many parameter combinations, so generate them sparsely,
                sparsity_factor = 120
                sparsity = TosaArgGen._calculate_sparsity(
                    len(paddings) * len(strides) * len(dilations), sparsity_factor
                )

        # Run through all the argument options creating valid test cases
        more_tests = True
        n = 0
        for a in accum_dtypes:
            for s in sorted(list(strides)):
                for p in sorted(list(paddings)):
                    for d in sorted(list(dilations)):
                        if more_tests and (n % sparsity == 0):
                            (
                                p,
                                remainders,
                                outputs,
                                outputs_no_stride,
                            ) = get_conv_output_info(p, s, d, fix_up_padding)
                            # Following is like checking each dimension N:
                            # (ifm_shape[N+1] - 1 + p[N*2] + p[N*2+1]) > d[N] * (k_shape[N] - 1)
                            if min(outputs_no_stride) <= 0:
                                # Not a valid operation
                                n += 1  # Increment count of tests
                                continue

                            if (
                                # the parameters must produce integer exact output
                                error_name != ErrorIf.ConvOutputShapeNonInteger
                                and max(remainders) == 0
                            ) or (
                                error_name == ErrorIf.ConvOutputShapeNonInteger
                                and max(remainders) > 0
                            ):
                                if (
                                    max_dim_size is not None
                                    and max(outputs) >= max_dim_size
                                ):
                                    # Test will consume too much memory - skip it
                                    logger.debug(
                                        "agConv: Convolution output too big - skipped"
                                    )
                                    continue

                                # Compliance - number of dot product calculations
                                if op["op"] == Op.DEPTHWISE_CONV2D:
                                    # N*OH*OW*C*M
                                    dots = gtu.product(
                                        (ifm_shape[0], *outputs, *filter_shape[2:])
                                    )
                                else:
                                    # N*OH*OW*OC or N*OD*OH*OW*OC
                                    dots = gtu.product(
                                        (ifm_shape[0], *outputs, filter_shape[0])
                                    )
                                args_dict = {
                                    "acc_type": a,
                                    "stride": s,
                                    "pad": p,
                                    "dilation": d,
                                    "kernel": k_shape,
                                    "ks": k_size,
                                    "dot_products": dots,
                                    "shape": ifm_shape,
                                }

                                # Support for larger values than 9 needs different delimiter
                                delim = "" if max(s + p + d) <= 9 else "x"
                                arg_list.append(
                                    (
                                        "acc{}_st{}_pad{}_dilat{}".format(
                                            testGen.typeStr(a),
                                            delim.join([str(x) for x in s]),
                                            delim.join([str(x) for x in p]),
                                            delim.join([str(x) for x in d]),
                                        ),
                                        args_dict,
                                    )
                                )
                                if (
                                    error_name
                                    and len(arg_list) >= TosaArgGen.MAX_TESTS_ERROR_IFS
                                ):
                                    # Found enough errors
                                    logger.debug(
                                        f"Skipping creating more conv error tests for {error_name}"
                                    )
                                    more_tests = False
                        n += 1

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtypes[0],
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agFullyConnected(testGen, rng, opName, shapeList, dtypes, error_name=None):

        assert isinstance(dtypes, (list, tuple)), f"{dtypes} unexpected"
        input_dtype = dtypes[0]

        if error_name == ErrorIf.WrongOutputType:
            accum_dtype = gtu.get_wrong_output_type(opName, rng, input_dtype)
        elif error_name == ErrorIf.WrongInputType:
            # Pick some potentially correct output dtype if input type is incorrect
            accum_dtype = DType.INT32
        else:
            accum_dtype = dtypes[-1]  # use output dtype as accum_dtype

        # Set up compliance info
        args_dict = {
            "acc_type": accum_dtype,
            "ks": int(shapeList[0][1]),  # Set KS = IC, from input A (N,IC)
            "dot_products": gtu.product((shapeList[0][0], shapeList[1][0])),
            "shape": shapeList[0],
        }

        arg_list = [(f"acc{testGen.typeStr(accum_dtype)}", args_dict)]

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            input_dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agMatMul(testGen, rng, opName, shapeList, dtype, error_name=None):
        # Get valid accumulate type(s)
        if dtype == DType.INT8:
            accum_dtypes = [DType.INT32]
        elif dtype == DType.INT16:
            accum_dtypes = [DType.INT48]
        elif dtype == DType.FP16:
            accum_dtypes = [DType.FP16, DType.FP32]
        elif dtype == DType.BF16:
            accum_dtypes = [DType.FP32]
        elif dtype == DType.FP32:
            accum_dtypes = [DType.FP32]
        elif dtype == DType.FP8E4M3 or dtype == DType.FP8E5M2:
            accum_dtypes = [DType.FP16]
        elif error_name is None:
            assert False, f"Invalid I/O DType for MatMul: {DTypeNames[dtype]}"

        if error_name == ErrorIf.WrongOutputType:
            # Get incorrect output dtype for ErrorIf case
            accum_dtypes = [gtu.get_wrong_output_type(opName, rng, dtype)]
        elif error_name == ErrorIf.WrongInputType:
            # Pick some potentially correct output dtype if input type is incorrect
            accum_dtypes = [DType.INT32]

        # Set up compliance info
        args_dict = {
            "ks": int(shapeList[0][2]),  # Set KS = C, from input A (N,H,C)
            # Set dot_products = N*H*W
            "dot_products": gtu.product(
                (shapeList[0][0], shapeList[0][1], shapeList[1][2])
            ),
            "shape": shapeList[0],
        }

        # Create arg tuple of string and dict
        arg_list = []
        for a in accum_dtypes:
            d = args_dict.copy()
            d["acc_type"] = a
            arg_list.append((f"acc{testGen.typeStr(a)}", d))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agTransposeConv2D(testGen, rng, opName, shapeList, dtypes, error_name=None):
        arg_list = []

        if testGen.args.level8k and error_name is not None:
            # Don't produce negative large tests
            return arg_list

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

        accum_dtypes = gtu.get_accum_dtypes_from_tgTypes(dtypes)

        if error_name == ErrorIf.WrongAccumulatorType:
            accum_dtypes = (
                [DType.BF16] if gtu.dtypeIsFloat(dtypes[0]) else [DType.INT16]
            )

        # Must be rank 4
        if error_name != ErrorIf.WrongRank:
            assert len(ifm_shape) == 4
            assert len(filter_shape) == 4

        k_shape = tuple(filter_shape[1:3])
        # compliance size - KS
        k_size = gtu.product((*k_shape, ifm_shape[3]))

        if not testGen.args.level8k:
            # Generate comprehensive argument lists
            # - except for named errors, which use specific invalid value(s)
            smallest_padding_size = -min(k_shape[0], k_shape[1]) + 1
            if error_name == ErrorIf.PadLargerEqualKernel:
                max_filter_size = -max(k_shape[0], k_shape[1])
                p_vals = [rng.choice(range(max_filter_size - 10, max_filter_size))]
            else:
                p_vals = [
                    x
                    for x in range(
                        smallest_padding_size, testGen.args.max_conv_padding + 1
                    )
                ]
            paddings = {x for x in itertools.product(*([p_vals] * 4))}
            if error_name == ErrorIf.StrideSmallerOne:
                # Can't use stride=0, as it is used to derive output shape, as a divisor
                s_vals = [rng.choice(range(-5, 0))]
            else:
                s_vals = [x for x in range(1, testGen.args.max_conv_stride + 1)]
            strides = {x for x in itertools.product(*([s_vals] * 2))}

            if not error_name and testGen.args.oversize:
                # add some oversize argument values
                if max(ifm_shape) < 64:
                    bigPadding = 9
                    paddings.update(
                        {
                            x
                            for x in itertools.product(
                                *([[smallest_padding_size, bigPadding]] * 4)
                            )
                        }
                    )
                bigStride = 8
                strides.update({x for x in itertools.product(*([[1, bigStride]] * 2))})

            # There are too many parameter combinations, so generate them sparsely,
            # very sparse for negative tests
            sparsity_factor = 2 if error_name else 10
            sparsity = len(paddings) * len(strides) // sparsity_factor + 1
            # If there are only a small number of tests, just select them all
            if sparsity < 13:
                sparsity = 1
            # To get a variety of parameter combinations sparsity should not be a
            # multiple of 2, 3 or 5
            while sparsity % 2 == 0 or sparsity % 3 == 0 or sparsity % 5 == 0:
                sparsity += 1
        else:
            # Only test 8k levels boundaries
            bigStride = testGen.TOSA_8K_LEVEL_MAX_STRIDE
            bigKernel = testGen.TOSA_8K_LEVEL_MAX_KERNEL
            bigPadding = bigKernel

            pad_shape = [0] * (len(k_shape) * 2)
            stride_shape = [1] * len(k_shape)
            # The point at which input dimension combined with the stride will
            # create large output sizes!
            LARGE_SIZE = 2
            for idx in range(len(k_shape)):
                pad_offset = idx * 2
                if k_shape[idx] == bigKernel:
                    # Set large stride
                    stride_shape[idx] = bigKernel
                    # Use negative output padding to reduce shape size
                    pad_shape[pad_offset] = -(bigPadding - 1)
                    if ifm_shape[idx + 1] > LARGE_SIZE:
                        pad_shape[pad_offset + 1] = -(bigPadding - 1)
                else:
                    # The other dimension should be the bigKernel
                    alt_idx = 1 - idx
                    if (
                        k_shape[alt_idx] == bigKernel
                        and ifm_shape[alt_idx + 1] < LARGE_SIZE
                    ):
                        # As the input is small, the large stride won't
                        # affect the output so we can add some padding
                        pad_shape[pad_offset + 1] = bigPadding

            strides = {tuple(stride_shape)}
            paddings = {tuple(pad_shape)}

            # Currently allow all combinations that are reasonable size
            sparsity = 1

        n = 0
        for a in accum_dtypes:
            for s in sorted(list(strides)):
                for p in sorted(list(paddings)):
                    if n % sparsity == 0:
                        # Determine the output shape
                        oh = (ifm_shape[1] - 1) * s[0] + p[0] + p[1] + k_shape[0]
                        ow = (ifm_shape[2] - 1) * s[1] + p[2] + p[3] + k_shape[1]
                        os = [ifm_shape[0], oh, ow, filter_shape[0]]

                        # N*OH*OW*OC
                        dots = gtu.product((ifm_shape[0], oh, ow, filter_shape[0]))
                        args_dict = {
                            "acc_type": a,
                            "stride": s,
                            "pad": p,
                            "kernel": k_shape,
                            "ks": k_size,
                            "dot_products": dots,
                            "shape": ifm_shape,
                            "out_shape": os,
                        }

                        # Support for larger values than 9 needs different delimiter
                        delim = "" if max(s + p) <= 9 else "x"
                        arg_list.append(
                            (
                                "acc{}_st{}_pad{}_os{}".format(
                                    testGen.typeStr(a),
                                    delim.join([str(x) for x in s]),
                                    delim.join([str(x) for x in p]),
                                    "x".join([str(x) for x in os]),
                                ),
                                args_dict,
                            )
                        )
                    n += 1

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtypes[0],
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

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

        if error_name is None and testGen.args.oversize:
            pad_values = [6, 7, 10, 13]
        elif error_name == ErrorIf.PadSmallerZero:
            pad_values = [x for x in range(-2, 0)]
        else:
            # Exhaustively test combinations of padding on each side of each dimension
            # - the range of padding values is defined by pad_min and pad_max
            pad_min, pad_max = 0, 1
            pad_values = [x for x in range(pad_min, pad_max + 1)]

        # Calculate pad combinations
        axis_pad_values = [x for x in itertools.product(pad_values, pad_values)]
        shape_pad_values = itertools.product(*([axis_pad_values] * rank))

        if dtype in [DType.BOOL, DType.INT8, DType.INT16, DType.INT32]:
            pad_const_int = rng.randNumberDType(dtype)
            pad_const_fp = 0
        elif gtu.dtypeIsFloat(dtype):
            pad_const_int = 0
            pad_const_fp = rng.randNumberDType(dtype)
        else:
            assert error_name == ErrorIf.WrongInputType
            pad_const_int = 0
            pad_const_fp = 0

        list_shape_pad_values = list(shape_pad_values)
        # If we are producing tests for rank 6 or greater use sparsity
        if len(list_shape_pad_values) > 1024:
            sparsity_factor = 2 if error_name else 120
            sparsity = TosaArgGen._calculate_sparsity(
                len(list_shape_pad_values), sparsity_factor
            )
        else:
            sparsity = 1

        # Build arg list
        arg_list = []
        for n, paddings in enumerate(list_shape_pad_values):
            paddings = list(paddings)
            args_valid = True

            if error_name == ErrorIf.PadSmallerZero:
                # Prevent negative output shapes while ensuring still testing for negative padding
                for i in range(rank):
                    dim_after_padding = (
                        paddings[i][0] + paddings[i][1] + shapeList[0][i]
                    )
                    if dim_after_padding < 1:
                        paddings[i] = (0, 0)
                if all([p > -1 for p in paddings[i]]):
                    args_valid = False
            if args_valid and n % sparsity == 0:
                # Work out name
                pad_list = []
                for r in range(rank):
                    pad_list.extend(paddings[r])

                delim = "" if max(pad_list) <= 9 else "x"
                name = "pad{}".format(delim.join([str(x) for x in pad_list]))

                args_dict = {
                    "pad": np.array(paddings),
                    "pad_const_int": pad_const_int,
                    "pad_const_fp": pad_const_fp,
                }
                arg_list.append((name, args_dict))

        if error_name == ErrorIf.PadSmallerZero and len(arg_list) == 0:
            logger.debug(
                f"agPad: No PadSmallerZero ErrorIf test created for input shape: {shapeList[0]}"
            )

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )

        # Return list of tuples: (arg_str, args_dict)
        return arg_list

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

        shape = shapeList[0]
        if error_name != ErrorIf.WrongRank:
            assert len(shape) == 4

        test_level8k = testGen.args.level8k and error_name is None

        startStride = 1 if error_name != ErrorIf.PoolingOutputShapeNonInteger else 2
        startKernel = 2
        startPad = 0
        if not test_level8k:
            # Generate comprehensive argument lists
            p_vals = [x for x in range(startPad, testGen.args.max_pooling_padding + 1)]
            paddings = {x for x in itertools.product(*([p_vals] * 4))}
            # Stride must be greater than 1 to force non-integer error
            s_vals = [
                x for x in range(startStride, testGen.args.max_pooling_stride + 1)
            ]
            strides = {x for x in itertools.product(*([s_vals] * 2))}
            k_vals = [
                x for x in range(startKernel, testGen.args.max_pooling_kernel + 1)
            ]
            kernels = {x for x in itertools.product(*([k_vals] * 2))}
            max_dim_size = None
        else:
            # Only test 8k levels
            bigStride = testGen.TOSA_8K_LEVEL_MAX_STRIDE
            bigKernel = testGen.TOSA_8K_LEVEL_MAX_KERNEL
            strides = {(1, bigStride), (bigStride, 4)}
            kernels = {(1, bigKernel), (bigKernel, 3)}
            paddings = set()
            for s in sorted(list(strides)):
                for k in sorted(list(kernels)):
                    padding = []
                    for idx in range(len(k)):
                        total_padding = s[idx] - shape[idx + 1] + k[idx]
                        while total_padding < 0:
                            # Must meet: shape + padding > kernel
                            total_padding += s[idx]
                        if total_padding < k[idx]:
                            padding.extend([0, total_padding])
                        else:
                            # Note this may produce padding >= k[idx] which is not
                            # allowed - but will be ignored in the creation loop below
                            padding.extend([k[idx] - 1, total_padding - (k[idx] - 1)])
                    paddings.add(tuple(padding))
            # Create a limit for the output dimensions size
            max_dim_size = testGen.TOSA_8K_LEVEL_MAX_KERNEL

        if opName == "max_pool2d":
            accum_dtypes = [None]  # max_pool has no accumulate dtype
        elif dtype == DType.INT8 or dtype == DType.INT16:
            accum_dtypes = [DType.INT32]
        elif dtype == DType.FP16:
            accum_dtypes = [DType.FP16, DType.FP32]
        elif dtype == DType.BF16 or dtype == DType.FP32:
            accum_dtypes = [DType.FP32]
        elif dtype == DType.FP8E4M3 or dtype == DType.FP8E5M2:
            accum_dtypes = [DType.FP16]
        elif error_name is None:
            assert False, f"Invalid I/O DType for pooling: {DTypeNames[dtype]}"
        else:
            # Set to something for the ErrorIf case which has
            # incorrect input data-type
            accum_dtypes = [DType.INT32]

        if error_name == ErrorIf.WrongAccumulatorType:
            accum_dtypes = list(gtu.usableDTypes(excludes=accum_dtypes))

        if not test_level8k:
            if testGen.args.oversize:
                # add some oversize argument values
                bigStride = 7
                bigKernel = 9
                strides.update(
                    {x for x in itertools.product(*([[startStride, bigStride]] * 2))}
                )
                kernels.update(
                    {x for x in itertools.product(*([[startKernel, bigKernel]] * 2))}
                )
                if max(shape) < 64:
                    # padding must be less than the kernel size
                    bigPadding = bigKernel - 1
                    paddings.update(
                        {x for x in itertools.product(*([[startPad, bigPadding]] * 4))}
                    )

            if error_name:
                # Cycle through all error_if tests but we only keep the first few
                sparsity = 1
            else:
                # There are too many parameter combinations, so generate them sparsely
                sparsity_factor = 500
                sparsity = (
                    len(paddings) * len(strides) * len(kernels) // sparsity_factor + 1
                )
        else:
            # We have already limited test output combinations for 8k tests
            sparsity = 1

        arg_str = (
            "acc{}_st{}_kern{}_pad{}"
            if accum_dtypes[0] is not None
            else "st{}_kern{}_pad{}"
        )

        def get_arg_list_element(accum, stride, pad, kern, dot_products=0, shape=[]):
            # Return tuple containing the formatted argument string and
            # the corresponding argument values in a dictionary

            # Support for larger values than 9 needs different delimiter
            delim = "" if max(stride + kern + pad) <= 9 else "x"
            arg_str_elems = [
                delim.join([str(x) for x in stride]),
                delim.join([str(x) for x in kern]),
                delim.join([str(x) for x in pad]),
            ]
            args_dict = {
                "stride": stride,
                "pad": pad,
                "kernel": kern,
                "dot_products": dot_products,  # Ignored for error tests
                "shape": shape,
                "ks": gtu.product(kern),  # avg_pool2d: KS = KX*KY
            }

            if accum is not None:
                arg_str_elems.insert(0, testGen.typeStr(accum))
                args_dict["acc_type"] = accum
            return (arg_str.format(*arg_str_elems), args_dict)

        more_tests = True
        n = 0
        for a in accum_dtypes:
            for s in sorted(list(strides)):
                for p in sorted(list(paddings)):
                    for k in sorted(list(kernels)):
                        if error_name in [
                            ErrorIf.StrideSmallerOne,
                            ErrorIf.KernelSmallerOne,
                            ErrorIf.PadSmallerZero,
                            ErrorIf.PadLargerEqualKernel,
                        ]:
                            sNew, pNew, kNew = TosaErrorIfArgGen.eiPoolingErrorIf(
                                rng, error_name, s, p, k
                            )
                            if None not in [sNew, pNew, kNew] and n % sparsity == 0:
                                arg_list.append(
                                    get_arg_list_element(a, sNew, pNew, kNew, shape)
                                )
                        elif (
                            more_tests
                            and n % sparsity == 0
                            # padding must not exceed the kernel size
                            and p[0] < k[0]
                            and p[1] < k[0]
                            and p[2] < k[1]
                            and p[3] < k[1]
                            # the padded shape must exceed the kernel size
                            and (shape[1] + p[0] + p[1]) > k[0]
                            and (shape[2] + p[2] + p[3]) > k[1]
                        ):
                            partial_h = shape[1] + p[0] + p[1] - k[0]
                            partial_w = shape[2] + p[2] + p[3] - k[1]
                            remainder_h = partial_h % s[0]
                            remainder_w = partial_w % s[1]
                            output_h = partial_h // s[0] + 1
                            output_w = partial_w // s[1] + 1
                            logger.debug(
                                f"agPooling: {shape} remainder=({remainder_h}, {remainder_w}) output=({output_h}, {output_w})"
                            )
                            if (
                                # the parameters must produce integer exact output
                                error_name != ErrorIf.PoolingOutputShapeNonInteger
                                and remainder_h == 0
                                and remainder_w == 0
                            ) or (
                                error_name == ErrorIf.PoolingOutputShapeNonInteger
                                and (remainder_h != 0 or remainder_w != 0)
                            ):
                                if (
                                    max_dim_size is not None
                                    and max(output_h, output_w) > max_dim_size
                                ):
                                    # Test will consume too much memory - skip it
                                    continue
                                # Dot products = N*OH*OW*C
                                dp = gtu.product(
                                    (shape[0], output_h, output_w, shape[3])
                                )
                                arg_list.append(
                                    get_arg_list_element(a, s, p, k, dp, shape)
                                )
                                if (
                                    error_name
                                    and len(arg_list) >= TosaArgGen.MAX_TESTS_ERROR_IFS
                                ):
                                    # Found enough errors
                                    logger.debug(
                                        f"Skipping creating more pooling error tests for {error_name}"
                                    )
                                    more_tests = False

                        n += 1

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )

        # Return list of tuples: (arg_str, args_dict)
        return arg_list

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

        # Enumerate the output types here
        if error_name == ErrorIf.WrongOutputType:
            dtypeList = TosaErrorIfArgGen.eiCastErrorIf(inDtype)
        elif inDtype == DType.INT8:
            dtypeList = [
                DType.BOOL,
                DType.INT16,
                DType.INT32,
                DType.FP16,
                DType.BF16,
                DType.FP32,
            ]
        elif inDtype == DType.INT16:
            dtypeList = [
                DType.BOOL,
                DType.INT8,
                DType.INT32,
                DType.FP16,
                DType.BF16,
                DType.FP32,
            ]
        elif inDtype == DType.INT32:
            dtypeList = [
                DType.BOOL,
                DType.INT8,
                DType.INT16,
                DType.FP16,
                DType.BF16,
                DType.FP32,
            ]
        elif inDtype == DType.BOOL:
            dtypeList = [DType.INT8, DType.INT16, DType.INT32]
        elif inDtype == DType.FP16:
            dtypeList = [
                DType.INT8,
                DType.INT16,
                DType.INT32,
                DType.FP32,
                DType.FP8E4M3,
                DType.FP8E5M2,
            ]
        elif inDtype == DType.BF16:
            dtypeList = [
                DType.INT8,
                DType.INT16,
                DType.INT32,
                DType.FP32,
                DType.FP8E4M3,
                DType.FP8E5M2,
            ]
        elif inDtype == DType.FP32:
            dtypeList = [
                DType.INT8,
                DType.INT16,
                DType.INT32,
                DType.FP16,
                DType.BF16,
                DType.FP8E4M3,
                DType.FP8E5M2,
            ]
        elif inDtype in [DType.FP8E4M3, DType.FP8E5M2]:
            dtypeList = [DType.FP16, DType.BF16, DType.FP32]
        elif error_name == ErrorIf.WrongInputType:
            # Pick some potentially correct output type for incorrect input type
            dtypeList = [DType.BOOL, DType.INT8, DType.INT16, DType.FP32]
        else:
            raise Exception("Unexpected input dtype: {}".format(inDtype))

        for dtype in dtypeList:
            arg_list.append(
                ("out{}".format(testGen.typeStr(dtype)), {"out_type": dtype})
            )

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )

        return arg_list

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

        # Enumerate the output types here
        for outDtype in [
            DType.UINT8,
            DType.INT8,
            DType.INT16,
            DType.INT32,
            DType.UINT16,
        ]:
            if (
                outDtype in [DType.UINT8, DType.INT8, DType.UINT16]
                and error_name == ErrorIf.OutputZeroPointNotZero
            ):
                continue
            if (
                outDtype != DType.UINT16
                and error_name == ErrorIf.U16OutputZeroPointNotValid
            ) or (
                inDtype != DType.UINT16
                and error_name == ErrorIf.U16InputZeroPointNotValid
            ):
                # ErrorIfs only valid with UINT16
                continue
            if (
                inDtype == DType.UINT8
                and outDtype not in [DType.INT8, DType.INT16]
                and error_name != ErrorIf.WrongOutputType
            ):
                # The only output dtypes for UINT8 are INT8/INT16, skip all others
                continue
            if (
                inDtype not in [DType.INT8, DType.INT16]
                and outDtype == DType.UINT8
                and error_name != ErrorIf.WrongOutputType
            ):
                # The only input dtypes for UINT8 are INT8/INT16, skip all others
                continue
            if (
                inDtype == DType.UINT16
                and outDtype != DType.INT16
                and error_name != ErrorIf.WrongOutputType
            ):
                # The only output dtype for UINT16 is INT16, skip all others
                continue
            if (
                inDtype != DType.INT16
                and outDtype == DType.UINT16
                and error_name != ErrorIf.WrongOutputType
            ):
                # The only input dtype for UINT16 is INT16, skip all others
                continue
            if (
                error_name == ErrorIf.WrongOutputType
                and not TosaErrorIfArgGen.eiRescaleWrongOutputType(inDtype, outDtype)
            ):
                continue

            for scale32 in [False, True]:
                if error_name == ErrorIf.ScaleTrue and not scale32:
                    continue
                elif error_name == ErrorIf.ScaleNotTrue and scale32:
                    continue
                for double_round in [False, True]:
                    if error_name == ErrorIf.ScaleNotTrue and not double_round:
                        continue
                    # Per_channel is only valid with rank > 0
                    pc_options = (False, True) if len(shapeList[0]) > 0 else (False,)
                    for per_channel in pc_options:

                        if (
                            inDtype == DType.INT48
                            and scale32
                            and error_name != ErrorIf.ScaleTrue
                        ):
                            # Illegal condition.  Must be scale32=False
                            continue
                        if (
                            double_round
                            and not scale32
                            and error_name != ErrorIf.ScaleNotTrue
                        ):
                            # Illegal condition.  ERROR_IF(!scale32 && double_round)
                            continue

                        if per_channel:
                            nc = shapeList[0][-1]
                        else:
                            nc = 1

                        in_type_width = gtu.dtypeWidth(inDtype)
                        out_type_width = gtu.dtypeWidth(outDtype)

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

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

                        if scale32:
                            # Cap the scaling at 2^31 - 1 for scale32
                            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)

                        logger.debug(
                            f"agRescale: {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
                            )

                        arg_list.append(
                            (
                                "out{}_sc{}_dr{}_pc{}".format(
                                    testGen.typeStr(outDtype),
                                    int(scale32),
                                    int(double_round),
                                    int(per_channel),
                                ),
                                {
                                    "output_dtype": outDtype,
                                    "scale": scale32,
                                    "double_round": double_round,
                                    "per_channel": per_channel,
                                    "multiplier": multiplier_arr,
                                    "shift": shift_arr,
                                },
                            )
                        )

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            inDtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agMul(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []

        if dtype is DType.INT32:
            for p in range(testGen.args.num_rand_permutations):

                shift = rng.randInt(0, 32)
                arg_list.append(("perm{}_shift{}".format(p, shift), {"shift": shift}))
        else:
            arg_list.append(("perm0_shift0", {"shift": 0}))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agArithmeticRightShift(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []

        for round in (True, False):
            args_dict = {
                "round": round,
            }
            arg_list.append((f"round{round}", args_dict))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agFFT2d(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []

        shape = shapeList[0]
        dot_products = gtu.product(shape)
        ks = 2 * shape[1] * shape[2]  # 2*H*W
        for inverse in (True, False):
            args_dict = {
                "dot_products": dot_products,
                "shape": shape,
                "ks": ks,
                "acc_type": dtype,
                "inverse": inverse,
            }
            arg_list.append((f"inverse{inverse}", args_dict))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agRFFT2d(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []

        shape = shapeList[0]
        dot_products = gtu.product(shape)
        ks = shape[1] * shape[2]  # H*W
        args_dict = {
            "dot_products": dot_products,
            "shape": shape,
            "ks": ks,
            "acc_type": dtype,
        }
        arg_list.append(("", args_dict))

        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        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)) + 1):
            if (val % i) == 0:
                factors.append(i)

        return factors

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

        origShape = shapeList[0]
        totalElements = gtu.product(origShape)
        factors = TosaArgGen.getFactors(totalElements)

        # Find new shapes up to the number of permutations asked for
        # This code is NOT fast.  Fortunately, the numbers are fairly small.
        for p in range(testGen.args.num_rand_permutations):
            # Rank from 1 to MAX_TENSOR_RANK
            newRank = rng.randInt(1, (gtu.MAX_TENSOR_RANK + 1))
            if len(factors) < newRank:
                continue

            # escape_counter limits the generation of new shapes to a reasonable time
            for escape_counter in range(100):

                # Generate the new shape of the chosen new rank
                newShape = []
                remainingElements = totalElements
                shuffledFactors = rng.permutation(factors)
                for i in range(1, newRank):
                    # pick rank-1 factors
                    newShape.append(shuffledFactors[0])
                    remainingElements = remainingElements // shuffledFactors[0]
                    shuffledFactors = rng.permutation(
                        TosaArgGen.getFactors(remainingElements)
                    )
                newShape.append(remainingElements)

                # Check for duplicates
                duplicate = False
                for name, args_dict in arg_list:
                    if args_dict["new_shape"] == newShape:
                        duplicate = True
                        break

                if not duplicate:
                    outShape = "x".join([str(x) for x in newShape])
                    arg_list.append(
                        (
                            "perm{}_rank{}_out{}".format(p, newRank, outShape),
                            {"new_shape": newShape},
                        )
                    )
                    # Found an output shape for this permutation
                    break

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )

        return arg_list

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

        ifm_shape = shapeList[0]

        if error_name == ErrorIf.IndexOutsideBounds:
            incorrect_large_index = range(len(ifm_shape) + 1, 2 * len(ifm_shape) + 1)
            incorrect_small_index = range(-len(ifm_shape), 0)
            permutations = [p for p in itertools.permutations(incorrect_large_index)]
            permutations.extend(
                [p for p in itertools.permutations(incorrect_small_index)]
            )
        elif error_name == ErrorIf.IndexUsedTwice:
            # Create list with a duplicated index
            perm_range = list(range(len(ifm_shape)))
            index_choice = rng.choice(range(len(perm_range)))
            perm_range[(index_choice + 1) % len(perm_range)] = perm_range[index_choice]
            permutations = [p for p in itertools.permutations(perm_range)]

        else:
            # Get all permutations
            permutations = [p for p in itertools.permutations(range(len(ifm_shape)))]

        # Limit to possible permutations from shape dimension or argument setting
        limit = min(len(permutations), testGen.args.num_rand_permutations)

        # Get random permutation generator that uses all permutations
        random_permutations = rng.permutation(permutations)

        # Create list of required amount of permutations
        arg_list = [
            ("perm{}".format(p), {"perms": random_permutations[p].tolist()})
            for p in range(limit)
        ]
        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

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

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

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

            for i in range(rank):
                if ifm_shape[i] > 1:
                    # Start from 0 to dimension size - 1 to leave room for slice of 1
                    start.append(rng.randInt(0, ifm_shape[i]))
                    # Size from 1 up to rest of room (dimension size - start)
                    size.append(rng.randInt(1, ifm_shape[i] + 1 - start[i]))

                    # Should never hit an invalid slice size
                    assert size[i] > 0 and (size[i] + start[i]) <= ifm_shape[i]
                else:
                    start.append(0)
                    size.append(1)

            # If ERROR_IF test required then incorrect start, size will be returned
            start, size = TosaErrorIfArgGen.eiSliceErrorIf(
                rng, error_name, ifm_shape, start, size
            )
            arg_list.append(("perm{}".format(p), {"start": start, "size": size}))

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agTile(testGen, rng, opName, shapeList, dtype, error_name=None):
        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):
                if ifm_shape[i] > 1000:
                    # Multiple of 1 if ifm_shape dimension is large to reduce
                    # tensor size
                    multiples.append(1)
                elif max(ifm_shape) > 1000:
                    multiples.append(2)
                else:
                    multiples.append(rng.randInt(1, 4))
            arg_list.append(("perm{}".format(p), {"multiples": multiples}))

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agResize(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []
        ifm_shape = shapeList[0]

        def get_aspect_ratio_resize_params():
            common_aspect_ratios = ((3, 2), (16, 9), (4, 3))
            aspect_ratio = rng.choice(common_aspect_ratios)
            invert = rng.choice((False, True))
            letterbox = rng.choice((False, True))

            scale_y_n = aspect_ratio[0] if invert else aspect_ratio[1]
            scale_x_n = aspect_ratio[1] if invert else aspect_ratio[0]
            scale_y_d = scale_x_d = 1
            offset_x = offset_y = 0

            if letterbox:
                max_border = scale_y_n
                border_y = rng.randInt(low=0, high=max_border)
                border_x = 0
            else:
                # Pillarboxing
                border_y = 0
                max_border = scale_x_n
                border_x = rng.randInt(low=0, high=max_border)

            scale = (scale_y_n, scale_y_d, scale_x_n, scale_x_d)
            offset = (offset_y, offset_x)
            border = (border_y, border_x)

            return scale, offset, border

        def get_upscale_downscale_params():
            valid_params = False
            while not valid_params:
                upscale = rng.choice((False, True))

                # True if sampling begins from (0,0). Otherwise (-0.5,-0.5)
                origin_sampling = rng.choice((False, True))

                if upscale:
                    shift = rng.randInt(low=1, high=4)
                    scale_x_d = scale_y_d = 1
                    scale_x_n = scale_y_n = (
                        1 << shift if origin_sampling else 2 << shift
                    )
                    border_x = border_y = 0 if origin_sampling else (1 << shift) - 1
                    offset_x = offset_y = 0 if origin_sampling else -(1 << shift) + 1
                else:
                    scale_x_n = 1
                    scale_y_n = 1

                    # Return list of valid scale_*_d values (max value 4) given input dim shape
                    def get_valid_denom(ifm_dim):
                        return [x for x in range(1, 5) if ifm_dim % x == 1]

                    # Generate list of valid downscale values and choose one randomly
                    valid_scale_y_ds = get_valid_denom(ifm_shape[1])
                    valid_scale_x_ds = get_valid_denom(ifm_shape[2])

                    if not valid_scale_y_ds and not valid_scale_x_ds:
                        # Bad parameters, skip
                        continue

                    if not valid_scale_y_ds:
                        scale_y_d = 1
                    else:
                        scale_y_d = rng.choice(valid_scale_y_ds)

                    if not valid_scale_x_ds:
                        scale_x_d = 1
                    else:
                        scale_x_d = rng.choice(valid_scale_x_ds)

                    border_x = border_y = 0
                    offset_y = rng.randInt(0, 16 * scale_y_n)
                    offset_x = rng.randInt(0, 16 * scale_x_n)
                valid_params = True

            scale = (scale_y_n, scale_y_d, scale_x_n, scale_x_d)
            offset = (offset_y, offset_x)
            border = (border_y, border_x)
            return scale, offset, border

        def get_rand_params():
            def fix_scale_to_max_scale(scale_n, scale_d, max_scale):
                scale = scale_n / scale_d
                if scale > max_scale:
                    factor = scale / max_scale
                    new_scale_d = math.ceil(scale_d * factor)
                    assert scale_n / new_scale_d <= max_scale
                    scale_d = new_scale_d
                return scale_d

            # Scale
            scale_y_n = rng.randInt(low=1, high=(1 << 11))
            scale_x_n = rng.randInt(low=1, high=(1 << 11))

            scale_y_d = rng.randInt(low=1, high=(16 * scale_y_n))
            scale_x_d = rng.randInt(low=1, high=(16 * scale_x_n))

            scale_y_d = fix_scale_to_max_scale(
                scale_y_n, scale_y_d, testGen.TOSA_8K_LEVEL_MAX_SCALE
            )
            scale_x_d = fix_scale_to_max_scale(
                scale_x_n, scale_x_d, testGen.TOSA_8K_LEVEL_MAX_SCALE
            )

            # Offsets and border within the scale
            offset_y = rng.randInt(low=-scale_y_n, high=(16 * scale_y_n))
            offset_x = rng.randInt(low=-scale_x_n, high=(16 * scale_x_n))
            border_y = rng.randInt(low=(-16 * scale_y_n), high=scale_y_n)
            border_x = rng.randInt(low=(-16 * scale_x_n), high=scale_x_n)

            scale = (scale_y_n, scale_y_d, scale_x_n, scale_x_d)
            offset = (offset_y, offset_x)
            border = (border_y, border_x)
            return scale, offset, border

        def get_level_8k_params():
            # Create 64x scale - 64/1 to 2048/32
            scale_d = rng.randInt(
                low=1, high=(1 << 11) / testGen.TOSA_8K_LEVEL_MAX_SCALE
            )
            scale_n = scale_d * testGen.TOSA_8K_LEVEL_MAX_SCALE
            # Create half to fifth scaling
            scale_d_alt = rng.randInt(low=2, high=6)
            scale_n_alt = 1
            switch = rng.choice((False, True))
            if switch:
                scale = (scale_n_alt, scale_d_alt, scale_n, scale_d)
            else:
                scale = (scale_n, scale_d, scale_n_alt, scale_d_alt)

            offset_y = rng.choice((-scale[0], 0, (16 * scale[0]) - 1))
            offset_x = rng.choice((-scale[2], 0, (16 * scale[2]) - 1))
            offset = (offset_y, offset_x)
            border_y = rng.choice((-16 * scale[0], 0, scale[0] - 1))
            border_x = rng.choice((-16 * scale[2], 0, scale[2] - 1))
            border = (border_y, border_x)
            return scale, offset, border

        for mode in [ResizeMode.NEAREST, ResizeMode.BILINEAR]:
            # Exclude illegal {mode, type} configurations.  Pick legal output types
            if mode == ResizeMode.NEAREST and dtype == DType.INT8:
                outputDTypeList = [DType.INT8]
            elif mode == ResizeMode.NEAREST and dtype == DType.INT16:
                outputDTypeList = [DType.INT16]
            elif mode == ResizeMode.BILINEAR and dtype == DType.INT8:
                outputDTypeList = [DType.INT32]
            elif mode == ResizeMode.BILINEAR and dtype == DType.INT16:
                outputDTypeList = [DType.INT48]
            elif dtype == DType.FP16:
                outputDTypeList = [DType.FP16]
            elif dtype == DType.BF16:
                outputDTypeList = [DType.BF16]
            elif dtype == DType.FP32:
                outputDTypeList = [DType.FP32]
            elif dtype == DType.FP8E4M3:
                outputDTypeList = [DType.FP8E4M3]
            elif dtype == DType.FP8E5M2:
                outputDTypeList = [DType.FP8E5M2]
            elif error_name == ErrorIf.WrongInputType:
                # If an incorrect input type is used then we set a 'correct'
                # output type to avoid other errors
                outputDTypeList = [DType.INT8, DType.INT16, DType.INT32]
            else:
                continue

            arg_str = "mode{}_out{}_sc{}x{}x{}x{}_off{}x{}_bor{}x{}"

            for outputDType in outputDTypeList:
                perm = 0
                while perm < testGen.args.num_rand_permutations:
                    # Random choice of type of params we are testing
                    if not testGen.args.level8k:
                        _rnd_param_fn = rng.choice(
                            (
                                get_rand_params,
                                get_upscale_downscale_params,
                                get_aspect_ratio_resize_params,
                            )
                        )
                        scale, offset, border = _rnd_param_fn()
                    else:
                        scale, offset, border = get_level_8k_params()

                    # Expand params for bounds-checking
                    (scale_y_n, scale_y_d, scale_x_n, scale_x_d) = scale
                    (offset_y, offset_x) = offset
                    (border_y, border_x) = border

                    # Make sure output dimensions OH and OW are integers
                    partial_output_y = (
                        (ifm_shape[1] - 1) * scale_y_n - offset_y + border_y
                    )
                    partial_output_x = (
                        (ifm_shape[2] - 1) * scale_x_n - offset_x + border_x
                    )
                    if error_name == ErrorIf.ResizeOutputShapeNonInteger:
                        # Look for non-integer test
                        if (
                            partial_output_y % scale_y_d == 0
                            and partial_output_x % scale_x_d == 0
                        ):
                            # Skip this test as it doesn't produce NonInteger output
                            if perm > 0:
                                perm += 1
                            continue
                    else:
                        # Alter the scaling factors to make the output integer
                        while partial_output_y % scale_y_d != 0:
                            scale_y_d -= 1
                        while partial_output_x % scale_x_d != 0:
                            scale_x_d -= 1
                        # Make sure we are still within max scaling
                        if (
                            scale_y_n / scale_y_d
                        ) > testGen.TOSA_8K_LEVEL_MAX_SCALE or (
                            scale_x_n / scale_x_d
                        ) > testGen.TOSA_8K_LEVEL_MAX_SCALE:
                            # Skip the test as it is using too large a scaling factor
                            if perm > 0:
                                perm += 1
                            continue

                    output_y = partial_output_y // scale_y_d + 1
                    output_x = partial_output_x // scale_x_d + 1

                    if (
                        output_y >= testGen.args.max_resize_output_dim
                        or output_x >= testGen.args.max_resize_output_dim
                    ) and error_name is None:
                        # Skip positive test if output dim will be too high
                        # Avoid high test latency and OOM issues
                        if not testGen.args.level8k or perm > 0:
                            perm += 1
                        continue

                    if (
                        output_y <= 0
                        or output_y >= gtu.MAX_RESIZE_DIMENSION
                        or output_x <= 0
                        or output_x >= gtu.MAX_RESIZE_DIMENSION
                    ):
                        # Output dimensions out of scope
                        if error_name is not None and perm > 0:
                            # As long as we have one ERROR_IF test, don't worry
                            # about creating all the other permutations
                            perm += 1
                        continue

                    if error_name == ErrorIf.ResizeOutputShapeMismatch and (
                        (
                            output_y + scale_y_d >= gtu.MAX_RESIZE_DIMENSION
                            and output_y - scale_y_d < 1
                        )
                        or (
                            output_x + scale_x_d >= gtu.MAX_RESIZE_DIMENSION
                            and output_x - scale_x_d < 1
                        )
                    ):
                        # Can't create a negative test with these params as it
                        # will create invalid output size
                        if perm > 0:
                            perm += 1
                        continue

                    scale = [scale_y_n, scale_y_d, scale_x_n, scale_x_d]
                    offset = [offset_y, offset_x]
                    border = [border_y, border_x]

                    # Common for all data types
                    if error_name is not None:
                        (
                            scale,
                            offset,
                            border,
                            outputDTypeNew,
                        ) = TosaErrorIfArgGen.eiResizeErrorIf(
                            rng,
                            error_name,
                            mode,
                            dtype,
                            shapeList,
                            outputDType,
                            scale,
                            offset,
                            border,
                        )
                    else:
                        outputDTypeNew = outputDType

                    arg_to_append = (
                        arg_str.format(
                            "N" if mode == ResizeMode.NEAREST else "B",
                            testGen.typeStr(outputDTypeNew),
                            scale[0],
                            scale[1],
                            scale[2],
                            scale[3],
                            offset[0],
                            offset[1],
                            border[0],
                            border[1],
                        ),
                        {
                            "mode": mode,
                            "scale": scale,
                            "offset": offset,
                            "border": border,
                            "output_dtype": outputDTypeNew,
                        },
                    )
                    if arg_to_append in arg_list:
                        # Skip already generated test params
                        continue

                    # Valid permutation
                    perm += 1
                    arg_list.append(arg_to_append)

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    @staticmethod
    def agTable(testGen, rng, opName, shapeList, dtype, error_name=None):
        arg_list = []

        if dtype == DType.INT8:
            table = np.int32(rng.integers(low=-128, high=128, size=[256])).tolist()
        else:  # INT16
            table = np.int32(rng.integers(low=-32768, high=32768, size=[513])).tolist()
            # Make sure all slopes are within REQUIRE min/max 16-bit int
            for idx in range(len(table) - 1):
                slope = table[idx + 1] - table[idx]
                # Alter the next table entry to force the slope to be ok
                if slope > 32767:
                    table[idx + 1] -= slope - 32767
                if slope < -32768:
                    table[idx + 1] -= slope + 32768
                slope = table[idx + 1] - table[idx]
                assert slope <= 32767 and slope >= -32768
        arg_list.append(
            (
                "",
                {"table": table},
            )
        )
        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

    def agCondIf(testGen, rng, opName, shapeList, dtype, error_name=None):
        # 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)), {"condition": c}))

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list

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

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

        # Now add data generator types
        arg_list = TosaArgGen._add_data_generators(
            testGen,
            opName,
            shapeList,
            dtype,
            arg_list,
            error_name,
        )
        # Return list of tuples: (arg_str, args_dict)
        return arg_list
