Could not find any supported formats consistent with input/output data types

I have build engine error for my plugin CTCGreedyDecoder.

CTCGreedyDecoder: could not find any supported formats consistent with input/output data types
[08/31/2020-17:39:41] [E] [TRT] ../builder/cudnnBuilderGraphNodes.cpp (743) - Misc Error in reportPluginError: 0 (could not find any supported formats consistent with input/output data types)
[08/31/2020-17:39:41] [E] [TRT] ../builder/cudnnBuilderGraphNodes.cpp (743) - Misc Error in reportPluginError: 0 (could not find any supported formats consistent with input/output data types)
[08/31/2020-17:39:41] [E] Prediction engine build failed.
&&&& FAILED TensorRT.platerecg # ./platerecg_debug --useDLACore=-1 --datadir=/usr/src/tensorrt/data/platerect/

Plugin together with application cpp file is attached. Recognition.cpp (28.1 KB)

My Plugin is

class CTCGreedyDecoder : public IPluginV2DynamicExt
{
public:
    //CTCGreedyDecoder has two inputs (import/transpose:0 (88, 1, 43), import/Fill:0 (1,)) 
    //and two outputs (import/CTCGreedyDecoder:0 (7, 2), import/ToInt32:0 (7,))
    CTCGreedyDecoder(const PluginFieldCollection& fc)
    {        
        (void) fc;
    }
    //data represents the class member variables data serialized in 
    //void serialize(void* buffer) const override
    //length is the length of data in serialization
    //Need to deserialize in this Constructor method    
    CTCGreedyDecoder(const void* data, size_t length)
    {
        const char* d = static_cast<const char*>(data);
        const char* const a = d;
        mDataType = static_cast<DataType>(read<int>(d));
        assert(d == a + length);
    }

    // It makes no sense to construct CTCGreedyDecoder without arguments.
    CTCGreedyDecoder() = delete;

    virtual ~CTCGreedyDecoder() {}

public:
    int getNbOutputs() const override
    {
        return 1;//it has one output
    }

    DimsExprs getOutputDimensions(int outputIndex, const DimsExprs* inputs, int nbInputs, IExprBuilder& exprBuilder) override
    {
        nvinfer1::DimsExprs output;
        output.nbDims=2;
        output.d[0] = exprBuilder.constant(1);
        output.d[1] = exprBuilder.constant(20);
        return output;
    }

    int initialize() override
    {        
        return 0;
    }

    void terminate() override
    {
        //To release memory
    }

    size_t getWorkspaceSize(const PluginTensorDesc* inputs, int nbInputs, const PluginTensorDesc* outputs,int 	nbOutputs) const
    {
        return 0;
    }
   
    int enqueue(const PluginTensorDesc *inputDesc, const PluginTensorDesc *outputDesc, const void *const *inputs, void *const *outputs, void *workspace,cudaStream_t stream) override
    {   
        Dims mInputDims = inputDesc[0].dims;
        int rows = mInputDims.d[0];
        int batch = mInputDims.d[1];   
        int widths = mInputDims.d[2]; 
        float* output = reinterpret_cast<float*>(outputs[0]);   
        interface(stream, inputs[0], output, rows, batch, widths);
        return 0;
    }
    //All class member private variables are serialized 
    //in the following two methods one after another
    //serializationSize is the size of all member variables
    size_t getSerializationSize() const override
    {
        size_t serializationSize = 0;        
        serializationSize += sizeof(static_cast<int>(mDataType));
        if (mDataType == DataType::kINT8)
        {
            serializationSize += sizeof(float) * 2;
        }      
        return serializationSize;
    }
    //serialize to char pointer
    void serialize(void* buffer) const override
    {
        char* d = static_cast<char*>(buffer);
        const char* const a = d;        
        write(d, static_cast<int>(mDataType));          
        assert(d == a + getSerializationSize());
    }
    //Plugin configuration for the input/output types, formats and sizes
    //PluginTensorDesc are fields that a plugin might see for an input or output.
    //it has 4 attributes (Dims, DataType, TensorFormat, float 	scale)
    //you can assert all match to the requirements
    //you can check all input/output types meets the expectations
    //For this CTCGreedyDecoder
    //first input is 3D vector 
    //second is 1D vector     
    void configurePlugin(const DynamicPluginTensorDesc* in, int nbInput, const DynamicPluginTensorDesc* out, int nbOutput) override
    {
        cout << "nbInput " << nbInput << " nbOutput " << nbOutput << endl;   
        assert(in && nbInput == 2);
        assert(out && nbOutput == 1);
        return ;
    }

    //! The combination of kLINEAR + kINT8/kHALF/kFLOAT is supported.
    bool supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) 
    {      
        cout << "nbInputs_here " << nbInputs << " nbOutputs_here " << nbOutputs << endl;   
        assert(nbInputs == 2 && nbOutputs == 1 && pos < nbInputs + nbOutputs);
        bool condition = inOut[pos].format == TensorFormat::kLINEAR;
        condition &= inOut[pos].type != DataType::kINT32;
        condition &= inOut[pos].type == inOut[0].type;
        return condition;
    }

    DataType getOutputDataType(int index, const DataType* inputTypes, int nbInputs) const override
    {
        cout << "inputTypes " << inputTypes << " nbInputs " << nbInputs << endl;
        assert(inputTypes && nbInputs == 2);
        (void) index;
        return inputTypes[0];
    }

    const char* getPluginType() const override
    {
        return "CTCGreedyDecoder";
    }

    const char* getPluginVersion() const override
    {
        return "1";
    }

    void destroy() override
    {
        delete this;
    }

    IPluginV2DynamicExt* clone() const override
    {
        auto* plugin = new CTCGreedyDecoder(*this);
        return plugin;
    }

    void setPluginNamespace(const char* libNamespace) override
    {
        mNamespace = libNamespace;
    }

    const char* getPluginNamespace() const override
    {
        return mNamespace.data();
    }
    

private:
    template <typename T>
    void write(char*& buffer, const T& val) const
    {
        *reinterpret_cast<T*>(buffer) = val;
        buffer += sizeof(T);
    }

    template <typename T>
    T read(const char*& buffer) const
    {
        T val = *reinterpret_cast<const T*>(buffer);
        buffer += sizeof(T);
        return val;
    }
    

private:    
    //This sparsetodense plugin doesn't need private members
    //All inputs/outputs are in the stream from previous outputs
    //so it is not necessary to have private members  
    DataType mDataType;    
    std::string mNamespace;
};

class CTCGreedyDecoderCreator : public IPluginCreator
{
public:
    const char* getPluginName() const override
    {
        return "CTCGreedyDecoder";
    }

    const char* getPluginVersion() const override
    {
        return "1";
    }

    const PluginFieldCollection* getFieldNames() override
    {
        return &mFieldCollection;
    }

    IPluginV2* createPlugin(const char* name, const PluginFieldCollection* fc) override
    {
        auto plugin = new CTCGreedyDecoder(*fc);
        mFieldCollection = *fc;
        mPluginName = name;
        return plugin;
    }
    
    IPluginV2* deserializePlugin(const char* name, const void* serialData, size_t serialLength) override
    {
        //serialData is all data serialized in fun void serialize(void* buffer) const override
        //serialLength is length of data seiralized in serialize(void* buffer)
        auto plugin = new CTCGreedyDecoder(serialData, serialLength);
        mPluginName = name;
        return plugin;
    }

    void setPluginNamespace(const char* libNamespace) override
    {
        mNamespace = libNamespace;
    }

    const char* getPluginNamespace() const override
    {
        return mNamespace.c_str();
    }

private:
    std::string mNamespace;
    std::string mPluginName;
    PluginFieldCollection mFieldCollection{0, nullptr};
};

REGISTER_TENSORRT_PLUGIN(CTCGreedyDecoderCreator);

Any problem at my plugin for this?

I solved the issue.
Print the format and type
cout <<"pos " << pos << " format " << (int)inOut[pos].format << " type " << (int)inOut[pos].type << endl; .
I have two inputs. One type is kFLOAT and another one is kINT32.

This condition check gives me error at runtime.

condition &= inOut[pos].type == inOut[0].type

1 Like

Hi @edit_or,
Glad to hear that this is resolved.
I was checking on this already.
Thanks!