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