cudnn_frontend_Operation.h
algorithm
array
functional
memory
sstream
utility
cudnn.h
cudnn_backend.h
cudnn_frontend_ConvDesc.h
cudnn_frontend_PointWiseDesc.h
cudnn_frontend_MatMulDesc.h
cudnn_frontend_ReductionDesc.h
cudnn_frontend_Tensor.h
cudnn_frontend_utils.h
cudnn_frontend_OperationGraph.h
cudnn_frontend.h
functional
limits
cudnn_frontend_MatMulDesc.h
cudnn.h
cudnn_frontend_PointWiseDesc.h
string
cudnn_frontend_Logging.h
cudnn_frontend_Tensor.h
exception
fstream
ostream
cudnn_frontend_Operation.h
vector
cudnn_frontend_ConvDesc.h
cudnn_backend.h
utility
array
sstream
cudnn_frontend_ReductionDesc.h
iostream
algorithm
cstring
cudnn_frontend_utils.h
memory
cudnn_backend_base.h
cudnn_frontend_Engine.h
cudnn_frontend_EngineConfig.h
cudnn_frontend_Heuristics.h
cudnn_frontend_get_plan.h
cudnn_frontend_EngineConfigGenerator.h
cudnn_frontend_ExecutionPlanCache.h
cudnn_frontend_Operation.h
cudnn_frontend_ExecutionPlan.h
cudnn_frontend_OperationGraph.h
cudnn_frontend.h
cudnn_frontend_find_plan.h
cudnn_frontend::Operation_v8
cudnn_frontend::OperationBuilder_v8
cudnn_frontend

    /*
    *Copyright(c)2021,NVIDIACORPORATION.Allrightsreserved.
    *
    *Permissionisherebygranted,freeofcharge,toanypersonobtaininga
    *copyofthissoftwareandassociateddocumentationfiles(the"Software"),
    *todealintheSoftwarewithoutrestriction,includingwithoutlimitation
    *therightstouse,copy,modify,merge,publish,distribute,sublicense,
    *and/orsellcopiesoftheSoftware,andtopermitpersonstowhomthe
    *Softwareisfurnishedtodoso,subjecttothefollowingconditions:
    *
    *Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedin
    *allcopiesorsubstantialportionsoftheSoftware.
    *
    *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSOR
    *IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,
    *FITNESSFORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALL
    *THEAUTHORSORCOPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHER
    *LIABILITY,WHETHERINANACTIONOFCONTRACT,TORTOROTHERWISE,ARISING
    *FROM,OUTOFORINCONNECTIONWITHTHESOFTWAREORTHEUSEOROTHER
    *DEALINGSINTHESOFTWARE.
    */

    #pragmaonce

    #include<algorithm>
    #include<array>
    #include<functional>
    #include<memory>
    #include<sstream>
    #include<utility>

    #include<cudnn.h>
    #include<cudnn_backend.h>

    #include"cudnn_frontend_ConvDesc.h"
    #include"cudnn_frontend_PointWiseDesc.h"
    #include"cudnn_frontend_MatMulDesc.h"
    #include"cudnn_frontend_ReductionDesc.h"
    #include"cudnn_frontend_Tensor.h"
    #include"cudnn_frontend_utils.h"

    namespacecudnn_frontend{
    classOperation_v8:publicBackendDescriptor{
    public:
    friendclassOperationBuilder_v8;
    std::string
    describe()constoverride{
    std::stringstreamss;
    ss<<"CUDNN_BACKEND_OPERATION:"
    <<"OpMode:"<<std::to_string(op_mode);
    ss<<std::hex<<"X"<<xdesc;
    ss<<std::hex<<"Y"<<ydesc;
    ss<<std::hex<<"W"<<wdesc;
    ss<<std::hex<<"B"<<bdesc;
    ss<<std::hex<<"DW"<<dwdesc;
    ss<<std::hex<<"DY"<<dydesc;
    ss<<std::hex<<"DX"<<dxdesc;
    ss<<std::hex<<"C"<<cdesc;
    ss<<std::hex<<"AMtrix"<<amatdesc;
    ss<<std::hex<<"BMtrix"<<bmatdesc;
    ss<<std::hex<<"CMtrix"<<cmatdesc;
    ss<<std::hex<<"P"<<pwdesc;
    ss<<std::hex<<"MatMul"<<matmuldesc;
    ss<<std::hex<<"Reduction"<<reductiondesc;
    ss<<std::dec<<"alphabetaType"<<alphabetaType;
    ss<<"Alpha:"<<alpha_s<<""<<alpha_d;
    ss<<"Alpha2:"<<alpha2_s<<""<<alpha2_d;
    ss<<"Beta:"<<beta_s<<""<<beta_d;
    returnss.str();
    }

    Operation_v8(Operation_v8&&from)=default;
    Operation_v8&
    operator= (Operation_v8&&from)=default;

    ManagedOpaqueDescriptor
    getOutputTensor(){
    return(op_mode==CUDNN_BACKEND_OPERATION_MATMUL_DESCRIPTOR)?cmatdesc:ydesc;
    }

    std::stringconst&
    getTag()const{
    returnoperationTag;
    }

    feature_vector_t
    getFeatureVector()const{
    returnfeature_vector;
    }

    ~Operation_v8()=default;

    private:
    Operation_v8()=default;
    Operation_v8(Operation_v8const&)=delete;
    Operation_v8&
    operator=(Operation_v8const&)=delete;

    cudnnBackendDescriptorType_top_mode=CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR;

    ManagedOpaqueDescriptorxdesc=nullptr;
    ManagedOpaqueDescriptorydesc=nullptr;
    ManagedOpaqueDescriptorwdesc=nullptr;
    ManagedOpaqueDescriptorbdesc=nullptr;
    ManagedOpaqueDescriptordydesc=nullptr;
    ManagedOpaqueDescriptordxdesc=nullptr;
    ManagedOpaqueDescriptordwdesc=nullptr;
    ManagedOpaqueDescriptorcdesc=nullptr;
    ManagedOpaqueDescriptoramatdesc=nullptr;
    ManagedOpaqueDescriptorbmatdesc=nullptr;
    ManagedOpaqueDescriptorcmatdesc=nullptr;
    ManagedOpaqueDescriptorpwdesc=nullptr;
    ManagedOpaqueDescriptormatmuldesc=nullptr;
    ManagedOpaqueDescriptorreductiondesc=nullptr;

    cudnnBackendAttributeType_talphabetaType=CUDNN_TYPE_FLOAT;
    floatalpha_s=1.0f,beta_s=.0f,alpha2_s=1.0f;
    doublealpha_d=1.0,beta_d=0.0,alpha2_d=1.0;
    int64_tpointwise_port_count=-1;
    cudnnPointwiseMode_tpointwise_mode;
    boolis_pointwise_activation_fwd_op=false;
    boolis_pointwise_activation_bwd_op=false;
    boolis_pointwise_math_op=false;
    std::stringoperationTag;
    feature_vector_tfeature_vector;
    };

    classOperationBuilder_v8{
    private:
    Operation_v8m_operation;
    boolis_convolution_op=false;
    boolis_pointwise_op=false;
    boolis_matmul_op=false;
    boolis_reduction_op=false;

    usingMessage_t=constchar*;

    int64_txTensor_dimA[CUDNN_DIM_MAX+1];
    int64_txTensor_strA[CUDNN_DIM_MAX+1];
    int64_twTensor_dimA[CUDNN_DIM_MAX+1];
    int64_twTensor_strA[CUDNN_DIM_MAX+1];
    int64_tyTensor_dimA[CUDNN_DIM_MAX+1];
    int64_tyTensor_strA[CUDNN_DIM_MAX+1];

    boolis2D=true;

    int64_tconv_padding[CUDNN_DIM_MAX];
    int64_tconv_dilation[CUDNN_DIM_MAX];
    int64_tconv_stride[CUDNN_DIM_MAX];
    int64_tmode;
    int64_txType,yType,wType,cType/*compute_precision*/;

    int64_ttensor_dims=0;

    Operation_v8&&
    build_reduction_op(){
    m_operation.operationTag="Reduction";
    autostatus=CUDNN_STATUS_SUCCESS;
    if((cudnnGetVersion()/100)==81){//workaroundforcudnn8.1
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_REDUCTION_OPERATOR,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.reductiondesc->get_backend_descriptor()));
    }else{
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_REDUCTION_DESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.reductiondesc->get_backend_descriptor()));
    }
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_REDUCTION_DESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_REDUCTION_XDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.xdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_REDUCTION_XDESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_REDUCTION_YDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.ydesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_REDUCTION_YDESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }
    returnstd::move(m_operation);
    }

    Operation_v8&&
    build_matmul_op(){
    m_operation.operationTag="Matmul";
    autostatus=CUDNN_STATUS_SUCCESS;
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_MATMUL_ADESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.amatdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_MATMUL_ADESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_MATMUL_BDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.bmatdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_MATMUL_BDESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_MATMUL_CDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.cmatdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_MATMUL_CDESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_MATMUL_DESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.matmuldesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_MATMUL_DESCFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }
    returnstd::move(m_operation);
    }

    Operation_v8&&
    build_pointwise_op(){
    autostatus=CUDNN_STATUS_SUCCESS;

    switch(m_operation.pointwise_mode){
    caseCUDNN_POINTWISE_ADD:
    m_operation.operationTag="Add";
    break;
    caseCUDNN_POINTWISE_MUL:
    m_operation.operationTag="Mul";
    break;
    #if(CUDNN_VERSION>=8300)
    caseCUDNN_POINTWISE_DIV:
    m_operation.operationTag="Div";
    break;
    caseCUDNN_POINTWISE_ADD_SQUARE:
    m_operation.operationTag="AddSquare";
    break;
    caseCUDNN_POINTWISE_EXP:
    m_operation.operationTag="Exp";
    break;
    caseCUDNN_POINTWISE_SUB:
    m_operation.operationTag="Sub";
    break;
    caseCUDNN_POINTWISE_CMP_EQ:
    m_operation.operationTag="CmpEq";
    break;
    caseCUDNN_POINTWISE_CMP_NEQ:
    m_operation.operationTag="CmpNeq";
    break;
    caseCUDNN_POINTWISE_CMP_GT:
    m_operation.operationTag="CmpGT";
    break;
    caseCUDNN_POINTWISE_CMP_GE:
    m_operation.operationTag="CmpGE";
    break;
    caseCUDNN_POINTWISE_CMP_LT:
    m_operation.operationTag="CmpLT";
    break;
    caseCUDNN_POINTWISE_CMP_LE:
    m_operation.operationTag="CmpLE";
    break;
    caseCUDNN_POINTWISE_LOGICAL_OR:
    m_operation.operationTag="LogicalOr";
    break;
    caseCUDNN_POINTWISE_LOGICAL_AND:
    m_operation.operationTag="LogicalAnd";
    break;
    caseCUDNN_POINTWISE_LOGICAL_NOT:
    m_operation.operationTag="LogicalNot";
    break;
    caseCUDNN_POINTWISE_LOG:
    m_operation.operationTag="Log";
    break;
    caseCUDNN_POINTWISE_NEG:
    m_operation.operationTag="Neg";
    break;
    caseCUDNN_POINTWISE_MOD:
    m_operation.operationTag="Mod";
    break;
    caseCUDNN_POINTWISE_POW:
    m_operation.operationTag="Pow";
    break;
    caseCUDNN_POINTWISE_ABS:
    m_operation.operationTag="Abs";
    break;
    caseCUDNN_POINTWISE_CEIL:
    m_operation.operationTag="Ceil";
    break;
    caseCUDNN_POINTWISE_FLOOR:
    m_operation.operationTag="Floor";
    break;
    caseCUDNN_POINTWISE_SIN:
    m_operation.operationTag="Sine";
    break;
    caseCUDNN_POINTWISE_COS:
    m_operation.operationTag="Cosine";
    break;
    caseCUDNN_POINTWISE_TAN:
    m_operation.operationTag="Tan";
    break;
    caseCUDNN_POINTWISE_RSQRT:
    m_operation.operationTag="RSqrt";
    break;
    #endif
    caseCUDNN_POINTWISE_MIN:
    m_operation.operationTag="Min";
    break;
    caseCUDNN_POINTWISE_MAX:
    m_operation.operationTag="Max";
    break;
    caseCUDNN_POINTWISE_SQRT:
    m_operation.operationTag="Sqrt";
    break;
    caseCUDNN_POINTWISE_RELU_FWD:
    m_operation.operationTag="ReluFwd";
    break;
    caseCUDNN_POINTWISE_TANH_FWD:
    m_operation.operationTag="TanhFwd";
    break;
    caseCUDNN_POINTWISE_SIGMOID_FWD:
    m_operation.operationTag="SigmoidFwd";
    break;
    caseCUDNN_POINTWISE_ELU_FWD:
    m_operation.operationTag="EluFwd";
    break;
    caseCUDNN_POINTWISE_GELU_FWD:
    m_operation.operationTag="GeluFwd";
    break;
    caseCUDNN_POINTWISE_SOFTPLUS_FWD:
    m_operation.operationTag="SoftplusFwd";
    break;
    caseCUDNN_POINTWISE_SWISH_FWD:
    m_operation.operationTag="SwishFwd";
    break;
    caseCUDNN_POINTWISE_RELU_BWD:
    m_operation.operationTag="ReluBwd";
    break;
    caseCUDNN_POINTWISE_TANH_BWD:
    m_operation.operationTag="TanhBwd";
    break;
    caseCUDNN_POINTWISE_SIGMOID_BWD:
    m_operation.operationTag="SigmoidBwd";
    break;
    caseCUDNN_POINTWISE_ELU_BWD:
    m_operation.operationTag="EluBwd";
    break;
    caseCUDNN_POINTWISE_GELU_BWD:
    m_operation.operationTag="GeluBwd";
    break;
    caseCUDNN_POINTWISE_SOFTPLUS_BWD:
    m_operation.operationTag="SoftplusBwd";
    break;
    caseCUDNN_POINTWISE_SWISH_BWD:
    m_operation.operationTag="SwishBwd";
    break;
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.pwdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTORFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_XDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.xdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_XDESCFailed");
    returnstd::move(m_operation);
    }

    if(!m_operation.is_pointwise_activation_bwd_op){
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_YDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.ydesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_YDESCFailed");
    returnstd::move(m_operation);
    }
    }else{
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_DYDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.dydesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_DYDESCFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_DXDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.dxdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_DXDESCFailed");
    returnstd::move(m_operation);
    }
    }

    void*alpha=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.alpha_s)
    :static_cast<void*>(&m_operation.alpha_d));
    void*alpha2=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.alpha2_s)
    :static_cast<void*>(&m_operation.alpha2_d));
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_ALPHA1,
    m_operation.alphabetaType,
    1,
    alpha);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_ALPHA1Failed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_ALPHA2,
    m_operation.alphabetaType,
    1,
    alpha2);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_ALPHA2Failed");
    returnstd::move(m_operation);
    }

    if(m_operation.pointwise_port_count==3&&!m_operation.is_pointwise_activation_bwd_op){
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_POINTWISE_BDESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.bdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_POINTWISE_BDESCFailed");
    returnstd::move(m_operation);
    }
    }
    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }
    returnstd::move(m_operation);
    }

    Operation_v8&&
    build_conv_backward_data(){
    m_operation.operationTag="ConvBwdData";

    autostatus=CUDNN_STATUS_SUCCESS;

    autodxdesc_=m_operation.dxdesc!=nullptr?m_operation.dxdesc:m_operation.xdesc;
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DX,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(dxdesc_->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DXFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_W,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.wdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_WFailed");
    returnstd::move(m_operation);
    }

    autodydesc_=m_operation.dydesc!=nullptr?m_operation.dydesc:m_operation.ydesc;
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DY,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(dydesc_->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DYFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_CONV_DESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.cdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_CONV_DESCFailed");
    returnstd::move(m_operation);
    }

    void*alpha=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.alpha_s)
    :static_cast<void*>(&m_operation.alpha_d));
    void*beta=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.beta_s)
    :static_cast<void*>(&m_operation.beta_d));
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_ALPHA,
    m_operation.alphabetaType,
    1,
    alpha);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_ALPHAFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_BETA,
    m_operation.alphabetaType,
    1,
    beta);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_BETAFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }
    getLogger()<<"Extractingthefeaturevector"<<std::endl;
    extract_feature_vector(CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR);
    returnstd::move(m_operation);
    }

    Operation_v8&&
    build_conv_backward_filter(){
    m_operation.operationTag="ConvBwdFilter";

    autostatus=CUDNN_STATUS_SUCCESS;

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_X,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.xdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_XFailed");
    returnstd::move(m_operation);
    }

    autodwdesc_=m_operation.dwdesc!=nullptr?m_operation.dwdesc:m_operation.wdesc;
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DW,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(dwdesc_->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DWFailed");
    returnstd::move(m_operation);
    }

    autodydesc_=m_operation.dydesc!=nullptr?m_operation.dydesc:m_operation.ydesc;
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DY,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(dydesc_->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DYFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_CONV_DESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.cdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttribute"
    "CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_CONV_DESCFailed");
    returnstd::move(m_operation);
    }
    void*alpha=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.alpha_s)
    :static_cast<void*>(&m_operation.alpha_d));
    void*beta=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.beta_s)
    :static_cast<void*>(&m_operation.beta_d));
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_ALPHA,
    m_operation.alphabetaType,
    1,
    alpha);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_ALPHAFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_BETA,
    m_operation.alphabetaType,
    1,
    beta);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_BETAFailed");
    returnstd::move(m_operation);
    }

    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }
    getLogger()<<"Extractingthefeaturevector"<<std::endl;
    extract_feature_vector(CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR);
    returnstd::move(m_operation);
    }

    Operation_v8&&
    build_conv_forward(){
    m_operation.operationTag="ConvFwd";

    autostatus=CUDNN_STATUS_SUCCESS;

    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_X,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.xdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_XFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_W,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.wdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_WFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_Y,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.ydesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_YFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_CONV_DESC,
    CUDNN_TYPE_BACKEND_DESCRIPTOR,
    1,
    &(m_operation.cdesc->get_backend_descriptor()));
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_CONV_DESCFailed");
    returnstd::move(m_operation);
    }
    void*alpha=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.alpha_s)
    :static_cast<void*>(&m_operation.alpha_d));
    void*beta=(m_operation.alphabetaType==CUDNN_TYPE_FLOAT?static_cast<void*>(&m_operation.beta_s)
    :static_cast<void*>(&m_operation.beta_d));
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_ALPHA,
    m_operation.alphabetaType,
    1,
    alpha);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_ALPHAFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendSetAttribute(m_operation.pointer->get_backend_descriptor(),
    CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_BETA,
    m_operation.alphabetaType,
    1,
    beta);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,
    status,
    "CUDNN_BACKEND_OPERATION:SetAttributeCUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_BETAFailed");
    returnstd::move(m_operation);
    }
    status=cudnnBackendFinalize(m_operation.pointer->get_backend_descriptor());
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnFinalizeFailed");
    returnstd::move(m_operation);
    }

    getLogger()<<"Extractingthefeaturevector"<<std::endl;
    extract_feature_vector(CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR);
    returnstd::move(m_operation);
    }

    voidextract_feature_vector(cudnnBackendDescriptorType_top_type){
    m_operation.feature_vector.reserve(50);

    m_operation.feature_vector.push_back(op_type);
    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(xTensor_dimA[i]);//n,c,(g),d,h,w
    }
    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(wTensor_dimA[i]);//n,c,(g),d,h,w
    }
    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(yTensor_dimA[i]);//n,c,(g),d,h,w
    }
    constintmax_spatial_dim=3;

    for(autoi=0;i<max_spatial_dim;i++){
    if(i==0&&is2D){
    m_operation.feature_vector.push_back(0);
    }else{
    m_operation.feature_vector.push_back(conv_padding[i]);
    }
    }
    for(autoi=0;i<max_spatial_dim;i++){
    if(i==0&&is2D){
    m_operation.feature_vector.push_back(0);
    }else{
    m_operation.feature_vector.push_back(conv_dilation[i]);
    }
    }
    for(autoi=0;i<max_spatial_dim;i++){
    if(i==0&&is2D){
    m_operation.feature_vector.push_back(0);
    }else{
    m_operation.feature_vector.push_back(conv_stride[i]);
    }
    }

    m_operation.feature_vector.push_back(xType);
    m_operation.feature_vector.push_back(wType);
    m_operation.feature_vector.push_back(yType);
    m_operation.feature_vector.push_back(cType);
    m_operation.feature_vector.push_back(mode);

    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(xTensor_strA[i]);//n,c,(g),d,h,w
    }
    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(wTensor_strA[i]);//n,c,(g),d,h,w
    }
    for(autoi=0;i<tensor_dims;i++){
    m_operation.feature_vector.push_back(yTensor_strA[i]);//n,c,(g),d,h,w
    }
    }

    cudnnStatus_t
    validate_matmul_op(Message_t&msg){
    if(m_operation.matmuldesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_MATMUL_DESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.amatdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_MATMUL_ADESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.bmatdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_MATMUL_BDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.cmatdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_MATMUL_CDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    returnCUDNN_STATUS_SUCCESS;
    }

    cudnnStatus_t
    validate_reduction_op(Message_t&msg){
    if(m_operation.reductiondesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_REDUCTION_DESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.xdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_REDUCTION_XDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.ydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_REDUCTION_YDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    returnCUDNN_STATUS_SUCCESS;
    }

    cudnnStatus_t
    validate_pointwise_op(Message_t&msg){
    if(m_operation.xdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_XDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.is_pointwise_math_op){
    if(m_operation.pointwise_port_count==3&&m_operation.bdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_BDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.ydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_YDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    }elseif(m_operation.is_pointwise_activation_fwd_op){
    if(m_operation.ydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_YDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    }elseif(m_operation.is_pointwise_activation_bwd_op){
    if(m_operation.dydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_DYDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.dxdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_POINTWISE_DXDESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    }else{
    msg="CUDNN_BACKEND_OPERATION:Unsupportedcudnnpointwisemode.CheckandsetCUDNN_POINTWISE_*";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    returnCUDNN_STATUS_SUCCESS;
    }

    cudnnStatus_t
    validate_convolution_op(Message_t&msg){
    if(m_operation.cdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_CONV_DESC";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR){
    if(m_operation.xdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_X";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.wdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_W";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.ydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_Y";
    returnCUDNN_STATUS_BAD_PARAM;
    }

    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR){
    if(m_operation.ydesc!=nullptr&&m_operation.dydesc!=nullptr){
    msg="CUDNN_BACKEND_OPERATION:Ambiguousspecification.ChooseandSetonlyoneofsetyDesc()orsetdyDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.ydesc==nullptr&&m_operation.dydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:ChooseandSetoneofsetyDesc()orsetdyDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.xdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_X";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.wdesc!=nullptr&&m_operation.dwdesc!=nullptr){
    msg="CUDNN_BACKEND_OPERATION:Ambiguousspecification.ChooseandSetonlyoneofsetwDesc()orsetdwDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.wdesc==nullptr&&m_operation.dwdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:ChooseandSetoneofsetwDesc()orsetdwDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR){
    if(m_operation.ydesc!=nullptr&&m_operation.dydesc!=nullptr){
    msg="CUDNN_BACKEND_OPERATION:Ambiguousspecification.ChooseandSetonlyoneofsetyDesc()orsetdyDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.ydesc==nullptr&&m_operation.dydesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:ChooseandSetoneofsetyDesc()orsetdyDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.wdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:CheckandSettheCUDNN_ATTR_OPERATION_CONVOLUTION_*_W";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.xdesc!=nullptr&&m_operation.dxdesc!=nullptr){
    msg="CUDNN_BACKEND_OPERATION:Ambiguousspecification.ChooseandSetonlyoneofsetxDesc()orsetdxDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    if(m_operation.xdesc==nullptr&&m_operation.dxdesc==nullptr){
    msg="CUDNN_BACKEND_OPERATION:ChooseandSetoneofsetxDesc()orsetdxDesc()";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    }else{
    msg="CUDNN_BACKEND_OPERATION:Unsupportedconvolutionoperation.CheckandsetCUDNN_BACKEND_OPERATION_CONVOLUTION_*_DESCRIPTOR";
    returnCUDNN_STATUS_BAD_PARAM;
    }
    returnCUDNN_STATUS_SUCCESS;
    }

    void
    copy_dims_and_strides(constint64_t*from,int64_t*to)const{
    for(autoi=0;i<CUDNN_DIM_MAX+1;i++){
    to[i]=from[i];
    }
    }

    public:
    auto
    setxDesc(ManagedOpaqueDescriptorconst&raw_tensor)->OperationBuilder_v8&{
    m_operation.xdesc=raw_tensor;
    return*this;
    }

    auto
    setxDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    m_operation.xdesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),xTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),xTensor_strA);
    tensor_dims=tensor.getDimensionCount();
    xType=tensor.getDataType();
    return*this;
    }
    auto
    setbDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    if(is_pointwise_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonPointwiseoperationdoesnotneedbTensor");
    }
    m_operation.bdesc=tensor.get_desc();
    return*this;
    }
    auto
    setyDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    m_operation.ydesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),yTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),yTensor_strA);
    yType=tensor.getDataType();
    return*this;
    }
    auto
    setwDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    if(is_convolution_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonConvolutionoperationdoesnotneedwTensor");
    }
    m_operation.wdesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),wTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),wTensor_strA);
    wType=tensor.getDataType();
    return*this;
    }

    auto
    setdyDesc(ManagedOpaqueDescriptorconst&raw_tensor)->OperationBuilder_v8&{
    m_operation.dydesc=raw_tensor;
    return*this;
    }
    auto
    setdyDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    m_operation.dydesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),yTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),yTensor_strA);
    yType=tensor.getDataType();
    return*this;
    }
    auto
    setdxDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    m_operation.dxdesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),xTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),xTensor_strA);
    tensor_dims=tensor.getDimensionCount();
    xType=tensor.getDataType();
    return*this;
    }
    auto
    setdwDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    m_operation.dwdesc=tensor.get_desc();
    copy_dims_and_strides(tensor.getDimArray(),wTensor_dimA);
    copy_dims_and_strides(tensor.getStrideArray(),wTensor_strA);
    wType=tensor.getDataType();
    return*this;
    }

    auto
    setcDesc(ConvDesc_v8const&conv)->OperationBuilder_v8&{
    if(is_convolution_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonConvolutionoperationdoesnotneedConvolutionDESCRIPTOR");
    }
    m_operation.cdesc=conv.get_desc();
    if(conv.getComputePrecision()==CUDNN_DATA_DOUBLE){
    m_operation.alphabetaType=CUDNN_TYPE_DOUBLE;
    }
    is2D=conv.getDimensionCount()==2;
    copy_dims_and_strides(conv.getPadding(),conv_padding);
    copy_dims_and_strides(conv.getDilation(),conv_dilation);
    copy_dims_and_strides(conv.getStride(),conv_stride);
    cType=conv.getComputePrecision();
    mode=conv.getMathMode();
    return*this;
    }
    auto
    setaMatDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    if(is_matmul_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonMatmuloperationdoesnotneedaMatrixTensor");
    }
    m_operation.amatdesc=tensor.get_desc();
    return*this;
    }
    auto
    setbMatDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    if(is_matmul_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonMatmuloperationdoesnotneedbMatrixTensor");
    }
    m_operation.bmatdesc=tensor.get_desc();
    return*this;
    }
    auto
    setcMatDesc(Tensor_v8const&tensor)->OperationBuilder_v8&{
    if(is_matmul_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonMatmuloperationdoesnotneedcMatrixTensor");
    }
    m_operation.cmatdesc=tensor.get_desc();
    return*this;
    }
    auto
    setmatmulDesc(MatMulDesc_v8const&matmulDesc)->OperationBuilder_v8&{
    if(is_matmul_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonMatmuloperationdoesnotneedMATMULDESCRIPTOR");
    }
    m_operation.matmuldesc=matmulDesc.get_desc();
    return*this;
    }
    auto
    setreductionDesc(ReductionDesc_v8const&reductionDesc)->OperationBuilder_v8&{
    if(is_reduction_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonReductionoperationdoesnotneedREDUCTIONDESCRIPTOR");
    }
    m_operation.reductiondesc=reductionDesc.get_desc();
    return*this;
    }
    auto
    setpwDesc(PointWiseDesc_v8const&pointWiseDesc)->OperationBuilder_v8&{
    if(is_pointwise_op==false){
    set_error_and_throw_exception(
    &m_operation,
    CUDNN_STATUS_BAD_PARAM,
    "CUDNN_BACKEND_OPERATION_*_DESCRIPTOR:NonPointwiseoperationdoesnotneedPOINTWISEDESCRIPTOR");
    }
    m_operation.pwdesc=pointWiseDesc.get_desc();
    m_operation.pointwise_port_count=pointWiseDesc.getPortCount();
    m_operation.pointwise_mode=pointWiseDesc.getPointWiseMode();

    m_operation.is_pointwise_math_op=((m_operation.pointwise_mode==CUDNN_POINTWISE_ADD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_MUL)||
    #if(CUDNN_VERSION>=8300)
    (m_operation.pointwise_mode==CUDNN_POINTWISE_DIV)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SUB)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_ADD_SQUARE)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_RSQRT)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SIN)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_COS)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_TAN)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_LOGICAL_OR)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_LOGICAL_AND)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_LOGICAL_NOT)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_EQ)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_NEQ)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_GT)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_GE)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_LT)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CMP_LE)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_LOG)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_NEG)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_MOD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_POW)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_ABS)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_CEIL)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_FLOOR)||
    #endif
    (m_operation.pointwise_mode==CUDNN_POINTWISE_MIN)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_MAX)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SQRT));

    m_operation.is_pointwise_activation_fwd_op=((m_operation.pointwise_mode==CUDNN_POINTWISE_RELU_FWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_TANH_FWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SIGMOID_FWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_ELU_FWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_GELU_FWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SOFTPLUS_FWD)||
    #if(CUDNN_VERSION>=8300)
    (m_operation.pointwise_mode==CUDNN_POINTWISE_EXP)||
    #endif
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SWISH_FWD));

    m_operation.is_pointwise_activation_bwd_op=((m_operation.pointwise_mode==CUDNN_POINTWISE_RELU_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_TANH_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SIGMOID_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_ELU_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_GELU_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SOFTPLUS_BWD)||
    (m_operation.pointwise_mode==CUDNN_POINTWISE_SWISH_BWD));

    return*this;
    }

    auto
    setAlpha(floatalpha)->OperationBuilder_v8&{
    m_operation.alpha_d=static_cast<double>(alpha);
    m_operation.alpha_s=alpha;
    return*this;
    }
    auto
    setAlpha(doublealpha)->OperationBuilder_v8&{
    m_operation.alpha_s=static_cast<float>(alpha);
    m_operation.alpha_d=alpha;
    return*this;
    }
    auto
    setAlpha2(floatalpha)->OperationBuilder_v8&{
    m_operation.alpha2_d=static_cast<double>(alpha);
    m_operation.alpha2_s=alpha;
    return*this;
    }
    auto
    setAlpha2(doublealpha)->OperationBuilder_v8&{
    m_operation.alpha2_s=static_cast<float>(alpha);
    m_operation.alpha2_d=alpha;
    return*this;
    }
    auto
    setBeta(floatbeta)->OperationBuilder_v8&{
    m_operation.beta_d=static_cast<double>(beta);
    m_operation.beta_s=beta;
    return*this;
    }
    auto
    setBeta(doublebeta)->OperationBuilder_v8&{
    m_operation.beta_s=static_cast<float>(beta);
    m_operation.beta_d=beta;
    return*this;
    }

    OperationBuilder_v8(cudnnBackendDescriptorType_tmode){
    m_operation.op_mode=mode;
    is_convolution_op=((m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR)||
    (m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR)||
    (m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR));

    is_pointwise_op=(m_operation.op_mode==CUDNN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR);
    is_matmul_op=(m_operation.op_mode==CUDNN_BACKEND_OPERATION_MATMUL_DESCRIPTOR);
    is_reduction_op=(m_operation.op_mode==CUDNN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR);
    }
    Operation_v8&&
    build(){
    if(m_operation.status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(
    &m_operation,m_operation.status,"CUDNN_BACKEND_OPERATION:Operationnotinitializedproperly");
    returnstd::move(m_operation);
    }

    Message_tmsg=nullptr;
    cudnnStatus_tstatus_=CUDNN_STATUS_SUCCESS;
    if(is_convolution_op){
    status_=validate_convolution_op(msg);
    }elseif(is_pointwise_op){
    status_=validate_pointwise_op(msg);
    }elseif(is_matmul_op){
    status_=validate_matmul_op(msg);
    }elseif(is_reduction_op){
    status_=validate_reduction_op(msg);
    }else{
    status_=CUDNN_STATUS_BAD_PARAM;
    msg="CUDNN_BACKEND_OPERATION_DESCRIPTOR:Unsupportedcudnnbackenddescriptortype.CheckandsetCUDNN_BACKEND_OPERATION_*_DESCRIPTOR";
    }
    if(status_!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status_,msg);
    returnstd::move(m_operation);
    }

    //Createthedescriptor.
    autostatus=m_operation.initialize_managed_backend_pointer(m_operation.op_mode);
    if(status!=CUDNN_STATUS_SUCCESS){
    set_error_and_throw_exception(&m_operation,status,"CUDNN_BACKEND_OPERATION:cudnnCreateFailed");
    returnstd::move(m_operation);
    }

    if(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR){
    returnbuild_conv_forward();
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR){
    returnbuild_conv_backward_filter();
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR){
    returnbuild_conv_backward_data();
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR){
    returnbuild_pointwise_op();
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_MATMUL_DESCRIPTOR){
    returnbuild_matmul_op();
    }elseif(m_operation.op_mode==CUDNN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR){
    returnbuild_reduction_op();
    }
    getLogger()<<"[cudnn_frontend]"<<m_operation<<std::endl;
    returnstd::move(m_operation);
    }
    };
    }