//
// SPDX-FileCopyrightText: Copyright 2023-2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the License); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Generated by tosaValidationGenerator for TOSA Specification 0.60.0
// Modify by implementing the constraints.

#include "tosa_error_checks.hpp"

#include "common/ordered_map.hpp"
#include "compiler/attributes.hpp"
#include "compiler/graph.hpp"
#include "compiler/operation.hpp"

using regor::DataType;
using regor::Operation;
using regor::ordered_map;
using regor::Tensor;
using regor::TensorConnection;
using regor::TensorUsage;

static bool shapeCheck(const TensorConnection *t1, int index1, const TensorConnection *t2, int index2)
{
    const auto &shape1 = t1->shape;
    const auto &shape2 = t2->shape;
    if ( index1 < 0 ) index1 = shape1.Size() + index1;
    if ( index2 < 0 ) index2 = shape2.Size() + index2;
    return (index1 >= 0 && shape1.Size() > index1 && index2 >= 0 && shape2.Size() > index2 && shape1[index1] == shape2[index2]);
}

static Shape broadcastShape(const Shape &shape1, const Shape &shape2)
{
    if ( shape1.Size() != shape2.Size() ) throw std::invalid_argument("ERROR_IF(rank(shape1) != rank(shape2))");
    Shape shape = shape1;
    for ( auto i = 0; i < shape.Size(); i++ )
    {
        if ( shape[i] == 1 )
        {
            shape[i] = shape2[i];
        }
        else
        {
            if ( shape2[i] != 1 && shape2[i] != shape[i] )
                throw std::invalid_argument("ERROR_IF(shape2[i] != 1 && shape2[i] != shape[i])");
        }
    }
    return shape;
}

namespace tosa
{
namespace validator
{
namespace checks
{
// Checks for TOSA Specification 0.60.0
void ErrorIfCheck_ai0sdq9wgm72(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ARGMAX,
    static constexpr char constraint[] = "ERROR_IF(axis < 0 || axis >= rank(shape1) || rank(shape1) > 4)";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::axis_attr_t>();
    const auto axis = attr->axis;
    if ( axis < 0 || axis >= rank || rank > 4 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_gpp861oen43y(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ARGMAX,
    static constexpr char constraint[] = "ERROR_IF(flatten(left_shape, right_shape) != shape)";
    const auto &inputShape = op->Input(TensorUsage::IFM)->shape;
    auto *attr = op->Attribute<regor::axis_attr_t>();
    const auto &expectedOutputShape = inputShape.Size() > 1 ? inputShape.Erase(attr->axis) : Shape{1};
    const auto &outputShape = op->Output(TensorUsage::OFM)->shape;
    if ( outputShape != expectedOutputShape ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1vu5c1tytwmhu(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != int8_t && input_zp != 0)";
    const auto *input = op->Input(TensorUsage::IFM);
    auto in_out_t = input->tensor->Type();
    auto &zp = input->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && input_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1n0denkrrrlr1(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, NEGATE,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != int8_t && output_zp != 0)";
    auto in_out_t = op->OFM()->Type();
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && output_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_36r4wpx3psd81(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(kernel_y < 1 || kernel_x < 1)";
    const auto *kernel = op->Kernel();
    if ( kernel->Size().y < 1 || kernel->Size().x < 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1lrylbkd3w7ix(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, CONV2D, DEPTHWISE_CONV2D, MAX_POOL2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(stride_y < 1 || stride_x < 1)";
    const auto *kernel = op->Kernel();
    if ( kernel->Stride().y < 1 || kernel->Stride().x < 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_ojmgqziimenu(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, CONV2D, DEPTHWISE_CONV2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0)";
    const auto *kernel = op->Kernel();
    if ( kernel->Padding().Top() < 0 || kernel->Padding().Bottom() < 0 || kernel->Padding().Left() < 0 ||
         kernel->Padding().Right() < 0 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3vqy81ueu5wjk(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(pad_right >= kernel_x || pad_left >= kernel_x)";
    const auto *kernel = op->Kernel();
    if ( kernel->Padding().Right() >= kernel->Size().x || kernel->Padding().Left() >= kernel->Size().x )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_125xuezh1964i(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(pad_top >= kernel_y || pad_bottom >= kernel_y)";
    const auto *kernel = op->Kernel();
    if ( kernel->Padding().Top() >= kernel->Size().y || kernel->Padding().Bottom() >= kernel->Size().y )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_fqta626ku4qe(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(OH != idiv_check(IH + pad_top + pad_bottom - kernel_y, stride_y) + 1)";
    auto IH = op->Input(TensorUsage::IFM)->shape.Height();
    auto OH = op->Output(TensorUsage::OFM)->shape.Height();
    int64_t tmp =
        static_cast<int64_t>(IH) + op->Kernel()->Padding().Top() + op->Kernel()->Padding().Bottom() -
        op->Kernel()->Size().y;
    if ( tmp % op->Kernel()->Stride().y != 0 ) throw std::invalid_argument(constraint);
    if ( OH != tmp / op->Kernel()->Stride().y + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_ycjhrvf2yigr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(OW != idiv_check(IW + pad_left + pad_right - kernel_x, stride_x) + 1)";
    auto IW = op->Input(TensorUsage::IFM)->shape.Width();
    auto OW = op->Output(TensorUsage::OFM)->shape.Width();
    int64_t tmp =
        static_cast<int64_t>(IW) + op->Kernel()->Padding().Left() + op->Kernel()->Padding().Right() -
        op->Kernel()->Size().x;
    if ( tmp % op->Kernel()->Stride().x != 0 ) throw std::invalid_argument(constraint);
    if ( OW != tmp / op->Kernel()->Stride().x + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1c57olj698f3d(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, MAX_POOL2D, RESIZE,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,C], input, [N,IH,IW,C]))";
    const auto *input = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(input, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(input, 3, output, 3) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_1hby1qurzja4f(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, DEPTHWISE_CONV2D, FULLY_CONNECTED, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(in_t != int8_t && input_zp != 0)";
    auto in_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_t != DataType::Int8 && input_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1md8k265hfj92(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, DEPTHWISE_CONV2D, FULLY_CONNECTED, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(weight_t != int8_t && weight_zp != 0)";
    auto weight_t = op->Input(TensorUsage::Weights)->tensor->Type();
    auto &zp = op->Input(TensorUsage::Weights)->quantization.zeroPoints;
    auto weight_zp = zp.empty() ? 0 : zp[0];
    if ( weight_t != DataType::Int8 && weight_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3fzsq78v5ypau(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(dilation_y < 1 || dilation_x < 1)";
    const auto *kernel = op->Kernel();
    if ( kernel->Dilation().y < 1 || kernel->Dilation().x < 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2vhj6e48eyzlr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(OH != idiv_check(IH - 1 + pad_top + pad_bottom - (KH - 1) * dilation_y, stride_y) + 1)";
    auto IH = op->Input(TensorUsage::IFM)->shape.Height();
    int WeightHeightIndex =
        (op->Type() == regor::OpType::DepthwiseConv2D) ?
            0 :
        (op->Type() == regor::OpType::Conv3D) ?
            2 :
            1;
    auto KH = op->Input(TensorUsage::Weights)->shape[WeightHeightIndex];
    auto OH = op->Output(TensorUsage::OFM)->shape.Height();
    const auto &padding = op->Kernel()->Padding();
    const auto &stride = op->Kernel()->Stride();
    const auto &dilation = op->Kernel()->Dilation();
    if ( KH < 1 || dilation.y < 0 || padding.Top() < 0 || padding.Bottom() < 0 || stride.y < 1 )
        throw std::invalid_argument(constraint);
    int64_t term1 = IH - 1LL + padding.Top() + padding.Bottom();
    int64_t term2 = (KH - 1LL) * dilation.y;
    if ( term1 < 0 || term2 < 0 || term2 > term1 ) throw std::invalid_argument(constraint);
    if ( term2 >= std::numeric_limits<int64_t>::max() - 3LL * std::numeric_limits<int>::max() - 1 )
        throw std::invalid_argument(constraint);

    int64_t numerator = term1 - term2;
    if ( numerator % stride.y != 0 ) throw std::invalid_argument(constraint);
    if ( OH != numerator / stride.y + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_147wc580l2tik(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(OW != idiv_check(IW - 1 + pad_left + pad_right - (KW - 1) * dilation_x, stride_x) + 1)";
    auto IW = op->Input(TensorUsage::IFM)->shape.Width();
    int WeightWitdhIndex =
        (op->Type() == regor::OpType::DepthwiseConv2D) ?
            1 :
        (op->Type() == regor::OpType::Conv3D) ?
            3 :
            2;
    auto KW = op->Input(TensorUsage::Weights)->shape[WeightWitdhIndex];
    auto OW = op->Output(TensorUsage::OFM)->shape.Width();
    const auto &padding = op->Kernel()->Padding();
    const auto &stride = op->Kernel()->Stride();
    const auto &dilation = op->Kernel()->Dilation();
    if ( KW < 1 || dilation.x < 0 || padding.Left() < 0 || padding.Right() < 0 || stride.x < 1 )
        throw std::invalid_argument(constraint);
    int64_t term1 = IW - 1LL + padding.Left() + padding.Right();
    int64_t term2 = (KW - 1LL) * dilation.x;
    if ( term1 < 0 || term2 < 0 || term2 > term1 ) throw std::invalid_argument(constraint);
    if ( term2 >= std::numeric_limits<int64_t>::max() - 3LL * std::numeric_limits<int>::max() - 1 )
        throw std::invalid_argument(constraint);
    int64_t numerator = term1 - term2;
    if ( numerator % stride.x != 0 ) throw std::invalid_argument(constraint);
    if ( OW != numerator / stride.x + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2rm8rnsdfn14h(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,OC], input, [N,IH,IW,IC]))";
    const auto *input = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(input, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_36emtx7zwkk96(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,OC], weight, [OC,KH,KW,IC]))";
    const auto *weights = op->Input(TensorUsage::Weights);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 3, weights, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_2r9jencgka20o(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,OC], bias, [OC]))";
    const auto *bias = op->Input(TensorUsage::Scales);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 3, bias, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_207p0r46d35m0(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(bias, [OC], weight, [OC,KH,KW,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *bias = op->Input(TensorUsage::Scales);
    if ( !shapeCheck(bias, 0, weight, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_cr43yjpqkcpd(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(weight, [OC,KH,KW,IC], input, [N,IH,IW,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *input = op->Input(TensorUsage::IFM);
    if ( !shapeCheck(weight, 3, input, 3) ) throw std::invalid_argument(constraint);  // IC
}

void ErrorIfCheck_341t6ysqc16b2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(pad_d0 < 0 || pad_d1 < 0 || pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0)";
    const auto &padding = op->Kernel()->Padding();
    if ( padding.Top() < 0 || padding.Bottom() < 0 || padding.Left() < 0 || padding.Right() < 0 || padding.Near() < 0 || padding.Far() < 0 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_uqm570jwaqb6(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(stride_d < 1 || stride_y < 1 || stride_x < 1)";
    const auto stride = op->Kernel()->Stride3D();
    if ( stride.z < 1 || stride.y < 1 || stride.x < 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_34iiwt6o66qfa(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(dilation_d < 1 || dilation_y < 1 || dilation_x < 1)";
    const auto dilation = op->Kernel()->Dilation3D();
    if ( dilation.z < 1 || dilation.y < 1 || dilation.x < 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_llbd3iugmek0(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(OD != idiv_check(ID - 1 + pad_d0 + pad_d1 - (KD - 1) * dilation_d, stride_d) + 1)";
    auto ID = op->Input(TensorUsage::IFM)->shape[1];
    auto KD = op->Input(TensorUsage::Weights)->shape[1];
    auto OD = op->Output(TensorUsage::OFM)->shape[1];
    const auto *kernel = op->Kernel();
    const auto &padding = kernel->Padding();
    const auto &dilation = kernel->Dilation3D();
    const auto &stride = kernel->Stride3D();
    if ( KD < 1 || dilation.z < 0 || padding.Near() < 0 || padding.Far() < 0 || stride.z < 1 )
        throw std::invalid_argument(constraint);
    int64_t term1 = ID - 1LL + padding.Near() + padding.Far();
    int64_t term2 = (KD - 1LL) * dilation.z;
    if ( term1 < 0 || term2 < 0 || term2 > term1 ) throw std::invalid_argument(constraint);
    if ( term2 >= std::numeric_limits<int64_t>::max() - 3LL * std::numeric_limits<int>::max() - 1 )
        throw std::invalid_argument(constraint);
    int64_t numerator = term1 - term2;
    if ( numerator % stride.z != 0 ) throw std::invalid_argument(constraint);
    if ( OD != numerator / stride.z + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1w510kxt5b2b2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OD,OH,OW,OC], input, [N,ID,IH,IW,IC]))";
    const auto *input = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(input, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_27g3t38z1of4h(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OD,OH,OW,OC], weight, [OC,KD,KH,KW,IC]))";
    const auto *weights = op->Input(TensorUsage::Weights);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 4, weights, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_95jvn4dzraol(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OD,OH,OW,OC], bias, [OC]))";
    const auto *bias = op->Input(TensorUsage::Scales);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 4, bias, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_21377cjnb1ox7(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(bias, [OC], weight, [OC,KD,KH,KW,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *bias = op->Input(TensorUsage::Scales);
    if ( !shapeCheck(bias, 0, weight, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_2cpco8ykx99sa(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(weight, [OC,KD,KH,KW,IC], input, [N,ID,IH,IW,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *input = op->Input(TensorUsage::IFM);
    if ( !shapeCheck(weight, 4, input, 4) ) throw std::invalid_argument(constraint);  // IC
}

void ErrorIfCheck_10sexbqileii7(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,C*M], input, [N,H,W,C]))";
    const auto *input = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(input, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_12rt0p658ac1(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OH,OW,C*M], bias, [C*M]))";
    const auto *output = op->Output(TensorUsage::OFM);
    const auto *bias = op->Input(TensorUsage::Scales);
    if ( !shapeCheck(output, 3, bias, 0) ) throw std::invalid_argument(constraint);  // C*M
    // Verify M & C from Weights, with shape [KH,KW,C,M]
    const auto &weightShape = op->Input(TensorUsage::Weights)->shape;
    if ( weightShape.Size() != 4 ) throw std::invalid_argument(constraint);
    auto CM = weightShape[2] * weightShape[3];
    if ( output->shape[3] != CM ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3cem64qtn6ajr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(weight, [KH,KW,C,M], input, [N,H,W,C]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *input = op->Input(TensorUsage::IFM);
    if ( !shapeCheck(weight, 2, input, 3) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_1hp4djlq1mi8i(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D, RFFT2D,
    static constexpr char constraint[] = "ERROR_IF(!power_of_two(H))";
    bool checkOk = (context.profile != GraphApi::PROFILE_BASELINE);
    checkOk = (op != nullptr);  // TODO: Implement check when MainInference is supported
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_20r08ymi6c43u(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D, RFFT2D,
    static constexpr char constraint[] = "ERROR_IF(!power_of_two(W))";
    bool checkOk = (context.profile != GraphApi::PROFILE_BASELINE);
    checkOk = (op != nullptr);  // TODO: Implement check  when MainInference is supported
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1xwwkxeypcw3j(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_imag, [N,H,W], input_real, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_vi3hzxbetjyg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_imag, [N,H,W], input_imag, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1m8qk2pbuovev(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_imag, [N,H,W], output_real, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1iv4j2x95j8dk(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_real, [N,H,W], input_real, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_316kdwzc9jf5x(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_real, [N,H,W], input_imag, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_tnr115b4spgw(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(input_imag, [N,H,W], input_real, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3ufiqep5ipuco(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FULLY_CONNECTED,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OC], input, [N,IC]))";
    const auto *input = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(input, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_3kcipzq18dxv9(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FULLY_CONNECTED,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OC], weight, [OC,IC]))";
    const auto *weights = op->Input(TensorUsage::Weights);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 1, weights, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_jcjmr2nnatvv(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FULLY_CONNECTED,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,OC], bias, [OC]))";
    const auto *bias = op->Input(TensorUsage::Scales);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 1, bias, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_qwmo2w7hxola(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FULLY_CONNECTED,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(bias, [OC], weight, [OC,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *bias = op->Input(TensorUsage::Scales);
    if ( !shapeCheck(bias, 0, weight, 0) ) throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_c9o11f07skde(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: FULLY_CONNECTED,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(weight, [OC,IC], input, [N,IC]))";
    const auto *weight = op->Input(TensorUsage::Weights);
    const auto *input = op->Input(TensorUsage::IFM);
    if ( !shapeCheck(weight, 1, input, 1) ) throw std::invalid_argument(constraint);  // IC
}

void ErrorIfCheck_1ellfcuw76b13(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MATMUL,
    static constexpr char constraint[] = "ERROR_IF(in_t != int8_t && (A_zp != 0 || B_zp != 0))";
    auto in_t = op->IFM(0)->Type();
    auto &zpA = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto A_zp = zpA.empty() ? 0 : zpA[0];
    auto &zpB = op->Input(TensorUsage::IFM1)->quantization.zeroPoints;
    auto B_zp = zpB.empty() ? 0 : zpB[0];
    if ( in_t != DataType::Int8 && (A_zp != 0 || B_zp != 0) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_h1uadv5irsu6(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MATMUL,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,H,W], A, [N,H,C]))";
    const auto *A = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(A, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(A, 1, output, 1) ) throw std::invalid_argument(constraint);  // H
}

void ErrorIfCheck_1kfh97qingywb(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MATMUL,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,H,W], B, [N,C,W]))";
    const auto *B = op->Input(TensorUsage::IFM1);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(B, 0, output, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(B, 2, output, 2) ) throw std::invalid_argument(constraint);  // W
}

void ErrorIfCheck_1azcq4511qzyx(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MATMUL,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(B, [N,C,W], A, [N,H,C]))";
    const auto *A = op->Input(TensorUsage::IFM);
    const auto *B = op->Input(TensorUsage::IFM1);
    if ( !shapeCheck(B, 0, A, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(B, 1, A, 2) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_15o9wo9pu7mrg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RFFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_imag, [N,H,W/2 + 1], input, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_13tqdu59nyxyh(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RFFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_imag, [N,H,W/2 + 1], output_real, [N,H,W/2 + 1]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2kgf2jejxlrr6(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RFFT2D,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output_real, [N,H,W/2 + 1], input, [N,H,W]))";
    bool checkOk = true;
    checkOk = (op != nullptr);  // TODO: Implement check
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_q9dl3x81rc4o(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(out_pad_top <= -KH || out_pad_bottom <= -KH)";
    int64_t KH = op->Input(TensorUsage::Weights)->shape.Height();
    const auto *k = op->Kernel();
    if ( k->Padding().Top() <= -KH || k->Padding().Bottom() <= -KH ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2rfkujt9lg7eq(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(out_pad_left <= -KW || out_pad_right <= -KW)";
    int64_t KW = op->Input(TensorUsage::Weights)->shape.Width();
    const auto *k = op->Kernel();
    if ( k->Padding().Left() <= -KW || k->Padding().Right() <= -KW ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3nelbnmxyemot(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE_CONV2D,
    auto *attr = op->Attribute<regor::transpose_conv2d_attr_t>();
    static constexpr char constraint[] = "ERROR_IF(OH != (IH - 1) * stride_y + out_pad_top + out_pad_bottom + KH)";
    auto IH = op->Input(TensorUsage::IFM)->shape.Height();
    auto KH = op->Input(TensorUsage::Weights)->shape.Height();
    auto OH = op->Output(TensorUsage::OFM)->shape.Height();
    auto *k = op->Kernel();
    const auto &outPadTBLR = attr->outPadTBLR;
    const auto &stride = k->Stride();
    if ( IH < 1 || stride.y < 1 ) throw std::invalid_argument(constraint);
    int64_t term1 = (IH - 1LL) * stride.y;
    if ( term1 >= std::numeric_limits<int64_t>::max() - 3LL * std::numeric_limits<int>::max() )
        throw std::invalid_argument(constraint);
    int64_t term2 = static_cast<int64_t>(outPadTBLR[0]) + outPadTBLR[1] + KH;
    if ( term1 < 0 || term2 < -term1 ) throw std::invalid_argument(constraint);
    uint64_t resultH = static_cast<uint64_t>(term1) + term2;
    if ( OH != static_cast<int64_t>(resultH) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_24conlof4w8eh(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE_CONV2D,
    auto *attr = op->Attribute<regor::transpose_conv2d_attr_t>();
    static constexpr char constraint[] = "ERROR_IF(OW != (IW - 1) * stride_x + out_pad_left + out_pad_right + KW)";
    auto IW = op->Input(TensorUsage::IFM)->shape.Width();
    auto KW = op->Input(TensorUsage::Weights)->shape.Width();
    auto OW = op->Output(TensorUsage::OFM)->shape.Width();
    auto *k = op->Kernel();
    const auto &outPadTBLR = attr->outPadTBLR;
    const auto &stride = k->Stride();
    if ( IW < 1 || stride.x < 1 ) throw std::invalid_argument(constraint);
    int64_t term1 = (IW - 1LL) * stride.x;
    if ( term1 >= std::numeric_limits<int64_t>::max() - 3LL * std::numeric_limits<int>::max() )
        throw std::invalid_argument(constraint);
    int64_t term2 = static_cast<int64_t>(outPadTBLR[2]) + outPadTBLR[3] + KW;
    if ( term1 < 0 || term2 < -term1 ) throw std::invalid_argument(constraint);
    uint64_t resultW = static_cast<uint64_t>(term1) + term2;
    if ( OW != static_cast<int64_t>(resultW) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_xod9coigx1x2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CLAMP,
    static constexpr char constraint[] = "ERROR_IF(max_val < min_val)";
    auto *attr = op->Attribute<regor::clamp_attr_t>();
    if ( attr->max < attr->min ) throw std::invalid_argument(constraint);
}

static bool broadcastOk(const Shape &outShape, const Shape &inShape)
{
    auto inRank = inShape.Size();
    auto outRank = outShape.Size();
    if ( outRank != inRank ) return false;
    for ( int i = 0; i < outRank; i++ )
    {
        if ( outShape[i] != inShape[i] && inShape[i] != 1 ) return false;
    }
    return true;
}

void ErrorIfCheck_1yism57if6v2z(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ADD, ARITHMETIC_RIGHT_SHIFT, BITWISE_AND, BITWISE_OR, BITWISE_XOR, INTDIV, LOGICAL_AND,
    //  LOGICAL_LEFT_SHIFT, LOGICAL_RIGHT_SHIFT, LOGICAL_OR, LOGICAL_XOR, MAXIMUM, MINIMUM, MUL, POW, SUB, SELECT,
    //  EQUAL, GREATER, GREATER_EQUAL,
    static constexpr char constraint[] = "ERROR_IF(apply_broadcast(shape, shape1, index))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;

    if ( !broadcastOk(shape, shape1) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3k5ug2w7gxc7r(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ADD, ARITHMETIC_RIGHT_SHIFT, BITWISE_AND, BITWISE_OR, BITWISE_XOR, INTDIV, LOGICAL_AND,
    //  LOGICAL_LEFT_SHIFT, LOGICAL_RIGHT_SHIFT, LOGICAL_OR, LOGICAL_XOR, MAXIMUM, MINIMUM, MUL, POW, SUB, SELECT,
    //  EQUAL, GREATER, GREATER_EQUAL,
    static constexpr char constraint[] = "ERROR_IF(apply_broadcast(shape, shape2, index))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shape2 = op->Input(TensorUsage::IFM1)->shape;

    if ( !broadcastOk(shape, shape2) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2gdayq6ofi7wx(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MUL,
    static constexpr char constraint[] = "ERROR_IF(in_t != int32_t && shift > 0)";
    auto in_t = op->IFM(0)->Type();
    auto *attr = op->Attribute<regor::mul_attr_t>();
    if ( in_t != DataType::Int32 && attr->shift > 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_38qvty7pudfz2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: NEGATE,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != int8_t && input1_zp != 0)";
    auto in_out_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input1_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && input1_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3tccsjner0km9(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SELECT,
    static constexpr char constraint[] = "ERROR_IF(apply_broadcast(shape, shape3, index))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shape3 = op->Input(TensorUsage::IFM2)->shape;

    if ( !broadcastOk(shape, shape3) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3tg4p2a5te0jy(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: REDUCE_ALL, REDUCE_ANY, REDUCE_MAX, REDUCE_MIN, REDUCE_PRODUCT, REDUCE_SUM,
    static constexpr char constraint[] = "ERROR_IF(axis < 0 || axis >= rank(shape1))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    const auto &inputShape = op->Input(TensorUsage::IFM)->shape;
    auto *attr = op->Attribute<regor::axis_attr_t>();
    if ( attr->axis < 0 || attr->axis >= rank ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_33exz9gn2i1wy(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: REDUCE_ALL, REDUCE_ANY, REDUCE_MAX, REDUCE_MIN, REDUCE_PRODUCT, REDUCE_SUM,
    static constexpr char constraint[] = "ERROR_IF(shape[axis] != 1)";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    auto *attr = op->Attribute<regor::axis_attr_t>();
    if ( shape[attr->axis] != 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_14slfd7r77hgh(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(axis < 0 || axis >= rank(shapes1[0]))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::axis_attr_t>();
    if ( attr->axis < 0 || attr->axis >= rank ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1fzhf02pkiw9z(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(shape[axis] != sum(shape1[k][axis] for all k))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &inputs = op->Inputs();
    auto axis = op->Attribute<regor::axis_attr_t>()->axis;
    int64_t sum = 0;
    for ( const auto &input : inputs )
    {
        auto inputDim = input.shape[axis];
        if ( inputDim < 0 || sum + inputDim > std::numeric_limits<int32_t>::max() )
            throw std::invalid_argument(constraint);
        sum += inputDim;
    }
    if ( shape[axis] != sum ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_16s99hvsej4fo(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(rank(input_shape) != rank(shapes1[0]))";
    const auto &inputs = op->Inputs();
    auto rank = inputs.front().shape.Size();
    bool checkOk = true;
    for ( const auto &input : inputs )
    {
        if ( input.shape.Size() != rank )
        {
            checkOk = false;
            break;
        }
    }
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_dctmd6sgn5n0(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(input_shape[index] != shapes1[0][index] && index != axis)";
    bool checkOk = true;
    const auto &inputs = op->Inputs();
    auto rank = inputs.front().shape.Size();
    auto *attr = op->Attribute<regor::axis_attr_t>();
    for ( const auto &input : inputs )
    {
        for ( int i = 0; i < rank; i++ )
        {
            if ( i != attr->axis && input.shape[i] != inputs.front().shape[i] )
            {
                checkOk = false;
                break;
            }
        }
        if ( !checkOk ) break;
    }
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_14z7y0qe9lwps(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: PAD,
    static constexpr char constraint[] = "ERROR_IF(rank(shape) != rank(shape1))";
    auto rank = op->Output(TensorUsage::OFM)->shape.Size();
    auto rank1 = op->Input(TensorUsage::IFM)->shape.Size();
    if ( rank != rank1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2rfef32dgp3be(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: PAD,
    static constexpr char constraint[] = "ERROR_IF(padding[i,0] < 0 || padding[i,1] < 0)";
    const auto *padding = op->Input(TensorUsage::Params);
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    if ( padding->shape.Elements() != 2LL * rank ) throw std::invalid_argument(constraint);
    const auto &paddingView = padding->tensor->View();
    if ( paddingView.ViewShape().Elements() != 2LL * rank ) throw std::invalid_argument(constraint);
    for ( int i = 0; i < rank; i++ )
    {
        if ( paddingView.Values<int32_t>()[2 * i] < 0 || paddingView.Values<int32_t>()[2 * i + 1] < 0 )
            throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_2sfcgak3rj1vs(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: PAD,
    static constexpr char constraint[] = "ERROR_IF(shape[i] != padding[i, 0] + shape1[i] + padding[i, 1])";
    const auto *padding = op->Input(TensorUsage::Params);
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;
    const auto rank = shape1.Size();
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    if ( padding->shape.Elements() != 2LL * rank ) throw std::invalid_argument(constraint);
    const auto &paddingView = padding->tensor->View();
    if ( paddingView.ViewShape().Elements() != 2LL * rank ) throw std::invalid_argument(constraint);
    for ( int i = 0; i < rank; i++ )
    {
        if ( shape[i] != paddingView.Values<int32_t>()[2 * i] + shape1[i] + paddingView.Values<int32_t>()[2 * i + 1] )
            throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_2a1jpygblc07i(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESHAPE, TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(tensor_size(shape1) != tensor_size(shape))";
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    if ( shape1.Elements() != shape.Elements() ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3hthyoock2ew5(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: REVERSE,
    static constexpr char constraint[] = "ERROR_IF(axis < 0 || axis >= rank(shape))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::axis_attr_t>();
    if ( attr->axis < 0 || attr->axis >= rank ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1nifeiq9rvmb8(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(rank(shape1) != length(start) || rank(shape1) != length(size))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    if ( rank != attr->begin.Size() || rank != attr->size.Size() ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_21rq6kn6p1yle(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE, TILE, TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(rank(shape1) != rank(shape))";
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    if ( shape1.Size() != shape.Size() ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3rghkieqip43o(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(start[index] < 0)";
    bool checkOk = true;
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    for ( int i = 0; i < rank; i++ )
    {
        if ( attr->begin[i] < 0 )
        {
            checkOk = false;
            break;
        }
    }
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1cyv9n59wyyyc(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(size[index] <= 0)";
    bool checkOk = true;
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    for ( int i = 0; i < rank; i++ )
    {
        if ( attr->size[i] < 0 )
        {
            checkOk = false;
            break;
        }
    }
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3oy2tclc6uhsu(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(start[index] + size[index] > shape1[index])";
    bool checkOk = true;
    const auto &shape = op->Input(TensorUsage::IFM)->shape;
    const auto rank = shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    for ( int i = 0; i < rank; i++ )
    {
        int64_t sliceSize = attr->begin[i] + attr->size[i];
        if ( sliceSize > shape[i] )
        {
            checkOk = false;
            break;
        }
    }
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_gpp3enlp1ddg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(shape[index] != size[index])";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto rank = shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    for ( int i = 0; i < rank; i++ )
    {
        if ( shape[i] != attr->size[i] ) throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_ix9div4ld46q(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SLICE,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(size, [rank(shape1)], start, [rank(shape1)]))";
    auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::slice_attr_t>();
    if ( attr->size.Size() != rank || attr->begin.Size() != rank ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3estuseky2gm2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TILE,
    static constexpr char constraint[] = "ERROR_IF(shape1[i] * multiples[i] != shape[i])";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;
    const auto view = op->Input(TensorUsage::Params)->tensor->View();
    Shape multiples(view.Buffer()->Data<int32_t>(), view.ViewShape().Elements());

    if ( multiples.Size() != shape.Size() ) throw std::invalid_argument(constraint);
    for ( int i = 0; i < shape.Size(); i++ )
    {
        int64_t shape1Dim = shape1[i];
        if ( shape1Dim < 0 || multiples[i] < 0 || shape[i] < 0 ) throw std::invalid_argument(constraint);
        int64_t result = shape1Dim * multiples[i];
        if ( result > std::numeric_limits<int32_t>::max() ) throw std::invalid_argument(constraint);
        if ( static_cast<int32_t>(result) != shape[i] ) throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_5bq1fx1llv8(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(index >= rank(shape1))";
    auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    const auto &perm = op->Attribute<regor::transpose_attr_t>()->perm;
    for ( int i = 0; i < perm.Size(); i++ )
    {
        if ( perm[i] >= rank ) throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_ckwpttzajw06(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(index < 0)";
    const auto &perm = op->Attribute<regor::transpose_attr_t>()->perm;
    for ( int i = 0; i < perm.Size(); i++ )
    {
        if ( perm[i] < 0 ) throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_2n1ratxgd89tx(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(indexes_used[index] == true)";
    auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    const auto &perm = op->Attribute<regor::transpose_attr_t>()->perm;
    Shape indexes_used(nullptr, rank);
    for ( int i = 0; i < perm.Size(); i++ )
    {
        if ( (perm[i] < 0 || perm[i] >= indexes_used.Size()) || indexes_used[perm[i]] )
            throw std::invalid_argument(constraint);
        indexes_used[perm[i]] = 1;
    }
}

void ErrorIfCheck_aizwrn95lb0l(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: TRANSPOSE,
    static constexpr char constraint[] = "ERROR_IF(shape1[perms[i]] != shape[i])";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shape1 = op->Input(TensorUsage::IFM)->shape;
    const auto &perm = op->Attribute<regor::transpose_attr_t>()->perm;
    for ( int i = 0; i < perm.Size(); i++ )
    {
        if ( perm[i] < 0 || perm[i] >= shape.Size() ) throw std::invalid_argument(constraint);
        if ( shape1[perm[i]] != shape[i] ) throw std::invalid_argument(constraint);
    }
}

void ErrorIfCheck_294afuxnedk9i(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: GATHER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,W,C], values, [N,K,C]))";
    const auto *values = op->Input(TensorUsage::IFM);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 0, values, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(output, 2, values, 2) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_27p0n0pjt2bd6(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: GATHER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(output, [N,W,C], indices, [N,W]))";
    const auto *indices = op->Input(TensorUsage::IFM1);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(output, 0, indices, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(output, 1, indices, 1) ) throw std::invalid_argument(constraint);  // W
}

void ErrorIfCheck_1uwmsen32dse1(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: GATHER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(indices, [N,W], values, [N,K,C]))";
    const auto *values = op->Input(TensorUsage::IFM);
    const auto *indices = op->Input(TensorUsage::IFM1);
    if ( !shapeCheck(indices, 0, values, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_3c5bq3iswjd1x(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(values_out, [N,K,C], values_in, [N,K,C]))";
    const auto *values_in = op->Input(TensorUsage::IFM);
    const auto *values_out = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(values_out, 0, values_in, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(values_out, 1, values_in, 1) ) throw std::invalid_argument(constraint);  // K
    if ( !shapeCheck(values_out, 2, values_in, 2) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_53yuoon46swi(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(values_out, [N,K,C], indices, [N,W]))";
    const auto *indices = op->Input(TensorUsage::IFM1);
    const auto *values_out = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(values_out, 0, indices, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_q9pgbwuvutqu(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(values_out, [N,K,C], input, [N,W,C]))";
    const auto *input = op->Input(TensorUsage::IFM2);
    const auto *values_out = op->Output(TensorUsage::OFM);
    if ( !shapeCheck(values_out, 0, input, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(values_out, 2, input, 2) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_1qdcccs22lqtr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(input, [N,W,C], values_in, [N,K,C]))";
    const auto *input = op->Input(TensorUsage::IFM2);
    const auto *values_in = op->Input(TensorUsage::IFM);
    if ( !shapeCheck(input, 0, values_in, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(input, 2, values_in, 2) ) throw std::invalid_argument(constraint);  // C
}

void ErrorIfCheck_2azl8wc8mbsrj(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(input, [N,W,C], indices, [N,W]))";
    const auto *input = op->Input(TensorUsage::IFM2);
    const auto *indices = op->Input(TensorUsage::IFM1);
    if ( !shapeCheck(input, 0, indices, 0) ) throw std::invalid_argument(constraint);  // N
    if ( !shapeCheck(input, 1, indices, 1) ) throw std::invalid_argument(constraint);  // W
}

void ErrorIfCheck_122a36k26p0au(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SCATTER,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(indices, [N,W], values_in, [N,K,C]))";
    const auto *values_in = op->Input(TensorUsage::IFM);
    const auto *indices = op->Input(TensorUsage::IFM1);
    if ( !shapeCheck(indices, 0, values_in, 0) ) throw std::invalid_argument(constraint);  // N
}

void ErrorIfCheck_3sfcy967j2w8w(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(max(OH,OW,IH,IW) >= 16384)";
    auto IW = op->Input(TensorUsage::IFM)->shape.Width();
    auto IH = op->Input(TensorUsage::IFM)->shape.Height();
    auto OW = op->Output(TensorUsage::OFM)->shape.Width();
    auto OH = op->Output(TensorUsage::OFM)->shape.Height();
    if ( std::max({OH, OW, IH, IW}) >= 16384 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1obslcewwn583(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(scale_y_n <= 0 || scale_y_d <= 0 || scale_x_n <= 0 || scale_x_d <= 0)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto scale_y_d = attr->scaleY.d;
    auto scale_y_n = attr->scaleY.n;
    auto scale_x_d = attr->scaleX.d;
    auto scale_x_n = attr->scaleX.n;
    if ( scale_y_n <= 0 || scale_y_d <= 0 || scale_x_n <= 0 || scale_x_d <= 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3oxfjen91qb6l(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(scale_y_n > (1 << 11) || scale_x_n > (1 << 11))";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto scale_y_n = attr->scaleY.n;
    auto scale_x_n = attr->scaleX.n;
    if ( scale_y_n > (1 << 11) || scale_x_n > (1 << 11) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1uo0z247e42af(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(scale_y_d >= 16 * scale_y_n || scale_x_d >= 16 * scale_x_n)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto scale_y_d = attr->scaleY.d;
    auto scale_y_n = attr->scaleY.n;
    auto scale_x_d = attr->scaleX.d;
    auto scale_x_n = attr->scaleX.n;
    if ( scale_y_d >= 16 * scale_y_n || scale_x_d >= 16 * scale_x_n ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1eovh9pyc6tyw(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(offset_y < -scale_y_n || offset_y >= 16 * scale_y_n)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto offset_y = attr->offset.y;
    auto scale_y_n = attr->scaleY.n;
    if ( offset_y < -scale_y_n || offset_y >= 16 * scale_y_n ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_24jsin2zkf4ug(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(offset_x < -scale_x_n || offset_x >= 16 * scale_x_n)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto offset_x = attr->offset.x;
    auto scale_x_n = attr->scaleX.n;
    if ( offset_x < -scale_x_n || offset_x >= 16 * scale_x_n ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_12uj5fltk5rbo(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(border_y < -16 * scale_y_n || border_y >= scale_y_n)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto border_y = attr->border.y;
    auto scale_y_n = attr->scaleY.n;
    if ( border_y < -16 * scale_y_n || border_y >= scale_y_n ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1py9f91imwjxe(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(border_x < -16 * scale_x_n || border_x >= scale_x_n)";
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto border_x = attr->border.x;
    auto scale_x_n = attr->scaleX.n;
    if ( border_x < -16 * scale_x_n || border_x >= scale_x_n ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_fn614zzdrdfd(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(OH != idiv_check((IH - 1) * scale_y_n - offset_y + border_y, scale_y_d) + 1)";
    auto IH = op->Input(TensorUsage::IFM)->shape.Height();
    auto OH = op->Output(TensorUsage::OFM)->shape.Height();
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto scale_y_n = attr->scaleY.n;
    auto scale_y_d = attr->scaleY.d;
    if ( scale_y_n > (1 << 11) || scale_y_d >= 16 * scale_y_n ) throw std::invalid_argument(constraint);
    auto offset_y = attr->offset.y;
    if ( offset_y < -scale_y_n || offset_y >= 16 * scale_y_n ) throw std::invalid_argument(constraint);
    if ( IH < 1 || IH >= std::numeric_limits<int16_t>::max() || scale_y_n <= 0 || scale_y_d <= 0 )
        throw std::invalid_argument(constraint);
    int64_t term1 = (IH - 1LL) * scale_y_n;
    if ( term1 >= std::numeric_limits<int64_t>::max() - 2LL * std::numeric_limits<int>::max() - 1 )
        throw std::invalid_argument(constraint);
    int64_t numerator = term1 - offset_y + attr->border.y;
    if ( numerator % scale_y_d != 0 ) throw std::invalid_argument(constraint);
    if ( OH != numerator / scale_y_d + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_338aejy0aeqeg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESIZE,
    static constexpr char constraint[] = "ERROR_IF(OW != idiv_check((IW - 1) * scale_x_n - offset_x + border_x, scale_x_d) + 1)";
    auto IW = op->Input(TensorUsage::IFM)->shape.Width();
    auto OW = op->Output(TensorUsage::OFM)->shape.Width();
    const auto *attr = op->Attribute<regor::resize_attr_t>();
    auto scale_x_n = attr->scaleX.n;
    auto scale_x_d = attr->scaleX.d;
    if ( scale_x_n > (1 << 11) || scale_x_d >= 16 * scale_x_n ) throw std::invalid_argument(constraint);
    auto offset_x = attr->offset.x;
    if ( offset_x < -scale_x_n || offset_x >= 16 * scale_x_n ) throw std::invalid_argument(constraint);
    if ( IW < 1 || IW >= std::numeric_limits<int16_t>::max() || scale_x_n <= 0 || scale_x_d <= 0 )
        throw std::invalid_argument(constraint);
    int64_t term1 = (IW - 1LL) * scale_x_n;
    if ( term1 >= std::numeric_limits<int64_t>::max() - 2LL * std::numeric_limits<int>::max() )
        throw std::invalid_argument(constraint);
    int64_t numerator = term1 - offset_x + attr->border.x;
    if ( numerator % scale_x_d != 0 ) throw std::invalid_argument(constraint);
    if ( OW != numerator / scale_x_d + 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_7p5naeft5ga8(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t != int8_t && in_t != uint8_t && in_t != uint16_t && input_zp != 0)";
    auto in_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_t != DataType::Int8 && in_t != DataType::UInt8 && in_t != DataType::UInt16 && input_zp != 0 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2hqaqrremyime(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(out_t != int8_t && out_t != uint8_t && out_t != uint16_t && output_zp != 0)";
    auto out_t = op->OFM()->Type();
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    if ( out_t != DataType::Int8 && out_t != DataType::UInt8 && out_t != DataType::UInt16 && output_zp != 0 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1wo90hck51cpk(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t == uint16_t && (input_zp != 0 || input_zp != 32768))";
    auto in_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_t == DataType::UInt16 && (input_zp != 0 && input_zp != 32768) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_v4b9g32rnf6p(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(out_t == uint16_t && (output_zp != 0 || output_zp != 32768))";
    auto out_t = op->OFM()->Type();
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    if ( out_t == DataType::UInt16 && (output_zp != 0 && output_zp != 32768) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_22dev8it3bz2g(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(scale32 && in_t == int48_t)";
    auto in_t = op->IFM(0)->Type();
    const auto *attr = op->Attribute<regor::rescale_attr_t>();
    if ( attr->scale32 && in_t == DataType::Int48 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3ms1pbkpa2td9(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(!scale32 && double_round)";
    const auto *attr = op->Attribute<regor::rescale_attr_t>();

    if ( !attr->scale32 && attr->double_round ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_31ty7f0kcbfxg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(shapeCheck(shift, [NC], multiplier, [NC]))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &shiftShape = op->Input(TensorUsage::Params)->shape;
    const auto &multiplierShape = op->Input(TensorUsage::Params1)->shape;
    auto outRank = shape.Size();
    const auto *attr = op->Attribute<regor::rescale_attr_t>();
    auto NC = attr->per_channel ? (outRank > 0 ? shape[outRank - 1] : 1) : 1;
    if ( shiftShape[0] != NC || multiplierShape[0] != NC ) throw std::invalid_argument(constraint);  // NC
}

static bool ShapeListsMatch(const ordered_map<TensorUsage, TensorConnection> &A,
    const std::vector<std::shared_ptr<Tensor>> &B, bool skipFirst = false)
{
    auto bSize = B.size();
    if ( bSize > size_t(std::numeric_limits<int32_t>::max()) ) return false;
    int64_t sizeDiff = A.size() - static_cast<int32_t>(bSize);
    if ( sizeDiff != (skipFirst ? 1 : 0) ) return false;
    auto iterA = A.begin();
    auto iterB = B.begin();
    if ( skipFirst )
    {
        iterA++;
    }
    while ( iterA != A.end() )
    {
        if ( iterA->shape != (*iterB)->StorageShape() ) return false;
        iterA++;
        iterB++;
    }
    return true;
}

static bool ShapeListsMatch(const ordered_map<TensorUsage, TensorConnection> &A, const ordered_map<TensorUsage, TensorConnection> &B)
{
    if ( A.size() != B.size() ) return false;
    auto iterA = A.begin();
    auto iterB = B.begin();

    while ( iterA != A.end() )
    {
        if ( iterA->shape != iterB->shape ) return false;
        iterA++;
        iterB++;
    }
    return true;
}

void ErrorIfCheck_1bm39avugkqqd(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(then_graph))";
    const auto *then_graph = context.GetGraph(op->Attribute<regor::cond_attr_t>()->then_branch.c_str());
    if ( !ShapeListsMatch(op->Inputs(), then_graph->Inputs(), true) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3tv3oatlz37e2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(else_graph))";
    const auto *else_graph = context.GetGraph(op->Attribute<regor::cond_attr_t>()->else_branch.c_str());
    if ( !ShapeListsMatch(op->Inputs(), else_graph->Inputs(), true) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_n7biu53x2n6k(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(output_list) != tosa_output_shape(then_graph))";
    const auto *then_graph = context.GetGraph(op->Attribute<regor::cond_attr_t>()->then_branch.c_str());
    if ( !ShapeListsMatch(op->Outputs(), then_graph->Outputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2fd4dk1zw032u(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(output_list) != tosa_output_shape(else_graph))";
    const auto *else_graph = context.GetGraph(op->Attribute<regor::cond_attr_t>()->else_branch.c_str());
    if ( !ShapeListsMatch(op->Outputs(), else_graph->Outputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_omgw2xdm6irr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF,
    static constexpr char constraint[] = "ERROR_IF(tensor_size(shape) != 1)";
    auto condSize = op->Input(TensorUsage::IFM)->shape.Elements();
    if ( condSize != 1 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_18hgmc3pexnw4(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_list_shape(output_list))";
    if ( !ShapeListsMatch(op->Inputs(), op->Outputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_12uu5ff3t3lv8(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(cond_graph))";
    const auto *cond_graph = context.GetGraph(op->Attribute<regor::while_attr_t>()->cond_branch.c_str());
    if ( !ShapeListsMatch(op->Inputs(), cond_graph->Inputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3puzf7van5acf(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(body_graph))";
    const auto *body_graph = context.GetGraph(op->Attribute<regor::while_attr_t>()->body_branch.c_str());
    if ( !ShapeListsMatch(op->Inputs(), body_graph->Inputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_8tihij7a5ep0(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tensor_list_shape(input_list) != tosa_output_shape(body_graph))";
    const auto *body_graph = context.GetGraph(op->Attribute<regor::while_attr_t>()->body_branch.c_str());
    if ( !ShapeListsMatch(op->Inputs(), body_graph->Outputs()) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3lu68v2531bjz(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tensor_size(tosa_output_shape(cond_graph)) != 1)";
    const auto *cond_graph = context.GetGraph(op->Attribute<regor::while_attr_t>()->cond_branch.c_str());
    const auto &condOutputs = cond_graph->Outputs();
    if ( condOutputs.size() != 1 || condOutputs.front()->StorageShape().Elements() != 1 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1fzl0zyxyd88z(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tosa_output_type(cond_graph) != bool_t)";
    const auto *cond_graph = context.GetGraph(op->Attribute<regor::while_attr_t>()->cond_branch.c_str());
    const auto &condOutputs = cond_graph->Outputs();
    if ( condOutputs.size() != 1 ) throw std::invalid_argument(constraint);
    auto type = condOutputs.front()->Type();
    if ( type != DataType::Bool8 && type != DataType::Bool ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_10u6py7exa66n(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CLAMP, SIGMOID, TANH, TABLE, REVERSE, CAST, RESCALE,
    static constexpr char constraint[] = "ERROR_IF(rankCheck(output, input))";
    const auto &outputShape = op->Output(TensorUsage::OFM)->shape;
    const auto &inputShape = op->Input(TensorUsage::IFM)->shape;
    if ( outputShape != inputShape ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_396rg8p65j58r(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ABS, BITWISE_NOT, CEIL, CLZ, EXP, FLOOR, LOG, LOGICAL_NOT, NEGATE, RECIPROCAL, RSQRT, IDENTITY,
    static constexpr char constraint[] = "ERROR_IF(rankCheck(output, input1))";
    const auto &outputShape = op->Output(TensorUsage::OFM)->shape;
    const auto &inputShape = op->Input(TensorUsage::IFM)->shape;
    if ( outputShape != inputShape ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3oet4aggtv528(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONST,
    static constexpr char constraint[] = "ERROR_IF(rankCheck(output, values))";
    const auto &outputShape = op->Output(TensorUsage::OFM)->shape;
    const auto &inputShape = op->Input(TensorUsage::IFM)->shape;
    if ( outputShape != inputShape ) throw std::invalid_argument(constraint);
}

}  // namespace checks
}  // namespace validator
}  // namespace tosa
namespace tosa
{
namespace validator
{
namespace checks
{
// Checks for TOSA specification 0.80.0
void ErrorIfCheck_4tfs5fdsigv(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != i8_t && input_zp != 0)";
    const auto *input = op->Input(TensorUsage::IFM);
    auto in_out_t = input->tensor->Type();
    auto &zp = input->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && input_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3nav30dsmv6gd(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: AVG_POOL2D, NEGATE,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != i8_t && output_zp != 0)";
    auto in_out_t = op->OFM()->Type();
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && output_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2p5uniza3kjyg(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, DEPTHWISE_CONV2D, FULLY_CONNECTED, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(in_t != i8_t && input_zp != 0)";
    auto in_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    if ( in_t != DataType::Int8 && input_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1gr4n0iszdlxr(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV2D, CONV3D, FULLY_CONNECTED, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(BC != OC && BC != 1)";
    const auto *bias = op->Input(TensorUsage::Scales);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( (bias->shape.Elements() != 1) && !shapeCheck(output, -1, bias, 0) )
        throw std::invalid_argument(constraint);  // OC
}

void ErrorIfCheck_318wf63fa7ql0(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONV3D, DEPTHWISE_CONV2D, FULLY_CONNECTED, TRANSPOSE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(weight_t != i8_t && weight_zp != 0)";
    auto weight_t = op->Input(TensorUsage::Weights)->tensor->Type();
    auto &zp = op->Input(TensorUsage::Weights)->quantization.zeroPoints;
    auto weight_zp = zp.empty() ? 0 : zp[0];
    if ( weight_t != DataType::Int8 && weight_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2d0jmyhr9lscf(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: DEPTHWISE_CONV2D,
    static constexpr char constraint[] = "ERROR_IF(BC != C*M && BC != 1)";
    const auto *bias = op->Input(TensorUsage::Scales);
    const auto *output = op->Output(TensorUsage::OFM);
    if ( (bias->shape.Elements() != 1) && !shapeCheck(output, 3, bias, 0) )
        throw std::invalid_argument(constraint);  // OC = C*M
}

void ErrorIfCheck_28csiz8foar64(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: MATMUL,
    static constexpr char constraint[] = "ERROR_IF(in_t != i8_t && (A_zp != 0 || B_zp != 0))";
    auto in_t = op->IFM(0)->Type();
    auto &zpA = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto A_zp = zpA.empty() ? 0 : zpA[0];
    auto &zpB = op->Input(TensorUsage::IFM1)->quantization.zeroPoints;
    auto B_zp = zpB.empty() ? 0 : zpB[0];
    if ( in_t != DataType::Int8 && (A_zp != 0 || B_zp != 0) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3tu2mqt96ickt(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ADD, INTDIV, MUL, SUB,
    static constexpr char constraint[] = "ERROR_IF(rank(shape) != 0 || rank(shape1) != 0 || rank(shape2) != 0)";
    bool checkOk = true;
    checkOk = (op != nullptr);  // Not implemented, this constraint for mode shape_t is gone in 0.90;
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1hynqeiugz9lt(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: ADD, ARITHMETIC_RIGHT_SHIFT, BITWISE_AND, BITWISE_OR, BITWISE_XOR, INTDIV, LOGICAL_AND,
    //  LOGICAL_LEFT_SHIFT, LOGICAL_RIGHT_SHIFT, LOGICAL_OR, LOGICAL_XOR, MAXIMUM, MINIMUM, MUL, POW, SUB, EQUAL,
    //  GREATER, GREATER_EQUAL,
    static constexpr char constraint[] = "ERROR_IF(shape != broadcast_shape(shape1, shape2))";
    auto shape1 = op->Input(TensorUsage::IFM)->shape;
    auto shape2 = op->Input(TensorUsage::IFM1)->shape;
    auto shape = op->Output(TensorUsage::OFM)->shape;
    if ( shape != broadcastShape(shape1, shape2) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1advtk54oueo2(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: NEGATE,
    static constexpr char constraint[] = "ERROR_IF(in_out_t != i8_t && input1_zp != 0)";
    auto in_out_t = op->IFM(0)->Type();
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input1_zp = zp.empty() ? 0 : zp[0];
    if ( in_out_t != DataType::Int8 && input1_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_192e2vu3t5aqm(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: SELECT,
    static constexpr char constraint[] = "ERROR_IF(shape != broadcast_shape(broadcast_shape(shape1, shape2), shape3))";
    auto shape1 = op->Input(TensorUsage::IFM)->shape;
    auto shape2 = op->Input(TensorUsage::IFM1)->shape;
    auto shape3 = op->Input(TensorUsage::IFM2)->shape;
    auto shape = op->Output(TensorUsage::OFM)->shape;
    if ( shape != broadcastShape(broadcastShape(shape1, shape2), shape3) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_5y7ov1oeymoa(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(axis < 0 || axis >= max(1,rank(shapes1[0])))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto *attr = op->Attribute<regor::axis_attr_t>();
    if ( attr->axis < 0 || attr->axis >= std::max<int>(1, rank) ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_oln8qpyh6lba(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(shape[axis] != sum(shape_dim(shapes1[k], axis) for all k))";
    const auto &shape = op->Output(TensorUsage::OFM)->shape;
    const auto &inputs = op->Inputs();
    auto axis = op->Attribute<regor::axis_attr_t>()->axis;
    int64_t sum = 0;
    for ( const auto &input : inputs )
    {
        auto inputDim = axis >= input.shape.Size() ? 1 : input.shape[axis];
        if ( inputDim < 0 || sum + inputDim > std::numeric_limits<int32_t>::max() )
            throw std::invalid_argument(constraint);
        sum += inputDim;
    }
    if ( shape[axis] != sum ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3thipxl768n8b(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(in_out_t == shape_t && rank(shape) > 1)";
    bool checkOk = true;
    checkOk = (op != nullptr);  // Not implemented, this constraint for mode shape_t is gone in 0.90;
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3bzibvkt1zqng(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: CONCAT,
    static constexpr char constraint[] = "ERROR_IF(index != axis && input_shape[index] != shapes1[0][index])";
    auto axis = op->Attribute<regor::axis_attr_t>()->axis;
    const auto &inputs = op->Inputs();
    const auto &shape0 = inputs.front().shape;
    for ( const auto &input : inputs )
    {
        if ( input.shape.Size() != shape0.Size() )
            throw std::invalid_argument("ERROR_IF(rank(input_shape) != rank(shapes1[0]))");
        for ( int index = 0; index < input.shape.Size(); index++ )
        {
            if ( index != axis && input.shape[index] != shape0[index] ) throw std::invalid_argument(constraint);
        }
    }
}

void ErrorIfCheck_171if2aq7ntnm(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: DIM,
    static constexpr char constraint[] = "ERROR_IF(axis >= rank(shape))";
    const auto rank = op->Input(TensorUsage::IFM)->shape.Size();
    auto axis = op->Attribute<regor::axis_attr_t>()->axis;
    if ( axis >= rank ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_1wbutqm1lq6qy(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t != i8_t && (in_t != i16_t || input_unsigned == False) && input_zp != 0)";
    auto bits = DataTypeSizeBits(op->IFM(0)->Type());
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( bits != 8 && (bits != 16 || !attr->input_unsigned) && input_zp != 0 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_2x883ovw61v55(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(out_t != i8_t && (out_t != i16_t || output_unsigned == False) && output_zp != 0)";
    auto bits = DataTypeSizeBits(op->OFM()->Type());
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( bits != 8 && (bits != 16 || !attr->output_unsigned) && output_zp != 0 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_7yfu5xo1ii36(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t == i16_t && input_unsigned == True && input_zp != 0 && input_zp != 32768)";
    auto bits = DataTypeSizeBits(op->IFM(0)->Type());
    auto &zp = op->Input(TensorUsage::IFM)->quantization.zeroPoints;
    auto input_zp = zp.empty() ? 0 : zp[0];
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( bits == 16 && attr->input_unsigned && input_zp != 0 && input_zp != 32768 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3kc0n1wjhehqz(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(out_t == i16_t && output_unsigned == True && output_zp != 0 && output_zp != 32768)";
    auto bits = DataTypeSizeBits(op->OFM()->Type());
    auto &zp = op->Output(TensorUsage::OFM)->quantization.zeroPoints;
    auto output_zp = zp.empty() ? 0 : zp[0];
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( bits == 16 && attr->output_unsigned && output_zp != 0 && output_zp != 32768 )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_3rzfyy6qi1bly(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(scale32 && in_t == i48_t)";
    auto in_t = op->IFM(0)->Type();
    const auto *attr = op->Attribute<regor::rescale_attr_t>();
    if ( attr->scale32 && DataTypeSizeBits(in_t) == 48 ) throw std::invalid_argument(constraint);
}

void ErrorIfCheck_23cyq2l8quj8p(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t == i16_t && out_t == i32_t && input_unsigned)";
    auto in_t = op->IFM(0)->Type();
    auto out_t = op->OFM()->Type();
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( DataTypeSizeBits(in_t) == 16 && DataTypeSizeBits(out_t) == 32 && attr->input_unsigned )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_13bcaagzywlqq(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: RESCALE,
    static constexpr char constraint[] = "ERROR_IF(in_t == i32_t && out_t == i16_t && output_unsigned)";
    auto in_t = op->IFM(0)->Type();
    auto out_t = op->OFM()->Type();
    auto *attr = op->Attribute<regor::sign_attr_t>();
    if ( DataTypeSizeBits(in_t) == 32 && DataTypeSizeBits(out_t) == 16 && attr->output_unsigned )
        throw std::invalid_argument(constraint);
}

void ErrorIfCheck_15kl5g5u1jrhq(const regor::Operation *op, [[maybe_unused]] const Context &context)
{
    // Operators: COND_IF, WHILE_LOOP,
    static constexpr char constraint[] = "ERROR_IF(tosa_nesting_depth >= MAX_NESTING)";
    bool checkOk = true;
    checkOk = (op != nullptr);  // Can't implement this check with current validation code
    if ( !checkOk ) throw std::invalid_argument(constraint);
}

}  // namespace checks
}  // namespace validator
}  // namespace tosa
