hello,
“trtexec --deploy=FaceBoxes.prototxt --output=detection_out” has already worked,but when parsing it in using the TensorRT caffe parser,the problem remains exits.
sample_face_detection: nvPluginsLegacy.cpp:1068: virtual nvinfer1::Dims nvinfer1::plugin::ConcatLegacy::getOutputDimensions(int, const nvinfer1::Dims*, int): Assertion `nbInputDims >= 1' failed.
Aborted (core dumped)
now,the priorbox layer and detection_out layer are all replaced by the Custom layer,we have implemented the IPluginExt class and IPluginFactory class as follows, Maybe it has a lot of problems. Please take a look at them and tell me how to solve this problem?
//priorbox layer plugin
class PriorBoxPlugin : nvinfer1::IPluginExt
{
public:
PriorBoxPlugin(HiPrioxBoxParameters params)
{
mPriorBoxParamters = params;
}
PriorBoxPlugin(const void*data ,size_t length)
{
const char* d = static_cast<const char*>(data), *a = d;
read(d,mDataType);
read(d,num_priors_);
read(d,mPriorBoxParamters);
read(d,mLayerWidth);
read(d,mLayerHeight);
read(d,mImgWidth);
read(d,mImgHeight);
assert(d == a+length);
}
~PriorBoxPlugin(){}
int getNbOutputs() const override
{
return 1;
}
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims)override
{
assert(index == 0 && nbInputDims == 2 && inputs[0].nbDims==3 );
//dim=layer_height * layer_width * num_priors_ * 4;
top_data_size = inputs[0].d[0] * inputs[0].d[1] *num_priors_ *4;
return Dims3(1, 2, top_data_size);
}
bool supportsFormat(DataType type, PluginFormat format) const override
{
return (type == DataType::kFLOAT || type == DataType::kHALF) && format == PluginFormat::kNCHW;
}
void configureWithFormat(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, DataType type, PluginFormat format, int maxBatchSize) override
{
assert((type == DataType::kFLOAT || type == DataType::kHALF) && format == PluginFormat::kNCHW);
assert(nbInputs == 2);
mDataType = type;
num_priors_ = mPriorBoxParamters.numAspectRatios * mPriorBoxParamters.numMinSize;
mLayerWidth = inputDims[0].d[1];
mLayerHeight = inputDims[0].d[2];
if (mPriorBoxParamters.imgH == 0 || mPriorBoxParamters.imgW == 0)
{
mImgWidth = inputDims[1].d[1];
mImgHeight = inputDims[1].d[2];
}
else
{
mImgWidth = mPriorBoxParamters.imgW;
mImgHeight = mPriorBoxParamters.imgH;
}
}
int initialize() override
{
return 0;
}
virtual void terminate() override { ; }
virtual size_t getWorkspaceSize(int batchSize) const override
{
return top_data_size * batchSize;
}
virtual int enqueue(int batchSize, const void*const *inputs, void** outputs, void*, cudaStream_t stream) override
{
float step_h,step_w;
if (mPriorBoxParamters.stepH == 0 ||mPriorBoxParamters.stepW == 0)
{
step_w = mImgWidth/mLayerWidth;
step_h = mImgHeight/mLayerHeight;
}
else
{
step_w = mPriorBoxParamters.stepW;
step_h = mPriorBoxParamters.stepH;
}
int dim = mLayerWidth * mLayerHeight * num_priors_ * 4;
float top_data[dim] = {0.};
int idx = 0;
for (int h = 0;h < mLayerHeight;++h)
{
for(int w=0;w<mLayerWidth;++w)
{
float center_x = (w + mPriorBoxParamters.offset) * step_w;
float center_y = (h + mPriorBoxParamters.offset) * step_h;
float box_width, box_height;
for (int s = 0;s<mPriorBoxParamters.numMinSize;++s)
{
int min_size_ = mPriorBoxParamters.minSize[s];
// first prior: aspect_ratio = 1, size = min_size
box_width = box_height = min_size_;
// xmin
top_data[idx++] = (center_x - box_width / 2.) / mImgWidth;
// ymin
top_data[idx++] = (center_y - box_height / 2.) / mImgHeight;
// xmax
top_data[idx++] = (center_x + box_width / 2.) / mImgWidth;
// ymax
top_data[idx++] = (center_y + box_height / 2.) / mImgHeight;
if (mPriorBoxParamters.numMaxSize > 0)
{
int max_size_ = mPriorBoxParamters.maxSize[s];
// second prior: aspect_ratio = 1, size = sqrt(min_size * max_size)
box_width = box_height = sqrt(min_size_ * max_size_);
// xmin
top_data[idx++] = (center_x - box_width / 2.) / mImgWidth;
// ymin
top_data[idx++] = (center_y - box_height / 2.) / mImgHeight;
// xmax
top_data[idx++] = (center_x + box_width / 2.) / mImgWidth;
// ymax
top_data[idx++] = (center_y + box_height / 2.) / mImgHeight;
}
// rest of priors
for (int r = 0; r < mPriorBoxParamters.numAspectRatios; ++r)
{
float ar = mPriorBoxParamters.aspectRatios[r];
if (fabs(ar - 1.) < 1e-6)
{
continue;
}
box_width = min_size_ * sqrt(ar);
box_height = min_size_ / sqrt(ar);
// xmin
top_data[idx++] = (center_x - box_width / 2.) / mImgWidth;
// ymin
top_data[idx++] = (center_y - box_height / 2.) / mImgHeight;
// xmax
top_data[idx++] = (center_x + box_width / 2.) / mImgWidth;
// ymax
top_data[idx++] = (center_y + box_height / 2.) / mImgHeight;
}
}
}
}
// clip the prior's coordidate such that it is within [0, 1]
if (mPriorBoxParamters.clip)
{
for (int d = 0; d < num_priors_; ++d)
{
top_data[d] = std::min(std::max((float)top_data[d], 0.0f), 1.0f);
}
}
float top_data1[dim] = {0};
// set the variance.
int count =0;
for (int h = 0; h < mLayerHeight; ++h) {
for (int w = 0; w < mLayerWidth; ++w) {
for (int i = 0; i < num_priors_; ++i) {
for (int j = 0; j < 4; ++j) {
top_data1[count] = mPriorBoxParamters.variance[j];
++count;
}
}
}
}
outputs[0] = top_data;
outputs[1] = top_data1;
return 0;
}
virtual size_t getSerializationSize() override
{
size_t size = sizeof(mDataType) + sizeof(num_priors_) + sizeof(mPriorBoxParamters)+sizeof(mLayerWidth)+sizeof(mLayerHeight)+sizeof(mImgWidth)+sizeof(mImgHeight);
return (size*type2size(mDataType));
}
virtual void serialize(void *buffer)override
{
char* d = static_cast<char*>(buffer), *a = d;
write(d,mDataType);
write(d,num_priors_);
write(d,mPriorBoxParamters);
write(d,mLayerWidth);
write(d,mLayerHeight);
write(d,mImgWidth);
write(d,mImgHeight);
assert(d == a + getSerializationSize());
}
int getTensorRTVersion()const override
{
return 0;
}
IPluginExt *clone()const override
{
return new PriorBoxPlugin(mPriorBoxParamters);
}
void destroy() { delete this; }
const char* getPluginType() const override
{
return "FCPlugin_TRT";
}
const char* getPluginVersion() const override
{
return "001";
}
private:
size_t type2size(DataType type) { return type == DataType::kFLOAT ? sizeof(float) : sizeof(__half); }
template<typename T> void write(char*& buffer, const T& val)
{
*reinterpret_cast<T*>(buffer) = val;
buffer += sizeof(T);
}
template<typename T> void read(const char*& buffer, T& val)
{
val = *reinterpret_cast<const T*>(buffer);
buffer += sizeof(T);
}
HiPrioxBoxParameters mPriorBoxParamters;
int num_priors_,top_data_size,mImgHeight,mImgWidth,mLayerWidth,mLayerHeight;
DataType mDataType{DataType::kFLOAT};
};
class PluginFactory : public nvinfer1::IPluginFactory,public nvcaffeparser1::IPluginFactoryExt
{
public:
virtual nvinfer1::IPlugin* createPlugin(const char* layerName, const nvinfer1::Weights* weights, int nbWeights) override;
nvinfer1::IPlugin* createPlugin(const char* layerName,const void* seriaData,size_t seriaLength)override;
// caffe parser plugin implementation
bool isPlugin(const char* name) override { return isPluginExt(name); }
bool isPluginExt(const char* name) override ;
void destroyPlugin();
void (*pluginDeleter)( nvinfer1::plugin::INvPlugin*) {[]( nvinfer1::plugin::INvPlugin* ptr) {ptr->destroy();}};
//priorbox layer
std::unique_ptr< PriorBoxPlugin> Inception3_conv_priorbox1_layer{nullptr};
std::unique_ptr< PriorBoxPlugin> Inception3_conv_priorbox2_layer{nullptr};
std::unique_ptr< PriorBoxPlugin> Inception3_conv_priorbox3_layer{nullptr};
std::unique_ptr< PriorBoxPlugin> conv6_priorbox_layer{nullptr};
std::unique_ptr< PriorBoxPlugin> conv7_priorbox_layer{nullptr};
//detection output layer
std::unique_ptr< nvinfer1::plugin::INvPlugin, decltype(pluginDeleter)> mDetection_out{nullptr, pluginDeleter};
};
//pluginfactory
/****************************************************/
nvinfer1::IPlugin* PluginFactory::createPlugin(const char* layerName, const nvinfer1::Weights* weights, int nbWeights)
{
assert(PluginFactory::isPluginExt(layerName));
std::cout << "==========createPlugin=========layerName:" << layerName << std::endl;
if(!strcmp(layerName,"Inception3/conv/priorbox1"))
{
assert(Inception3_conv_priorbox1_layer.get() == nullptr);
HiPrioxBoxParameters params;
float minSize[1] = {32};
float aspectRatios[1] = {1};
params.minSize = minSize;
params.maxSize = nullptr;
params.aspectRatios = aspectRatios;
params.numMinSize = 1;
params.numMaxSize = 0;
params.numAspectRatios = 1;
params.flip = true;
params.clip = true;
params.variance[0] = 0.1;
params.variance[1] = 0.1;
params.variance[2] = 0.2;
params.variance[3] = 0.2;
params.imgH = 0;
params.imgW = 0;
params.stepH = 0;
params.stepW = 0;
params.offset = 0.5;
Inception3_conv_priorbox1_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(params));
std::cout << "==========createPlugin succ=========layerName:" << layerName << std::endl;
return (nvinfer1::IPlugin*)Inception3_conv_priorbox1_layer.get();
}
else if (!strcmp(layerName,"Inception3/conv/priorbox2"))
{
assert(Inception3_conv_priorbox2_layer.get() == nullptr);
HiPrioxBoxParameters params;
float minSize[1] = {64};
float aspectRatios[1] = {1};
params.minSize = minSize;
params.maxSize = nullptr;
params.aspectRatios = aspectRatios;
params.numMinSize = 1;
params.numMaxSize = 0;
params.numAspectRatios = 1;
params.flip = true;
params.clip = true;
params.variance[0] = 0.1;
params.variance[1] = 0.1;
params.variance[2] = 0.2;
params.variance[3] = 0.2;
params.imgH = 0;
params.imgW = 0;
params.stepH = 0;
params.stepW = 0;
params.offset = 0.5;
Inception3_conv_priorbox2_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(params));
return (nvinfer1::IPlugin*)Inception3_conv_priorbox2_layer.get();
}
else if (!strcmp(layerName,"Inception3/conv/priorbox3"))
{
assert(Inception3_conv_priorbox3_layer.get() == nullptr);
HiPrioxBoxParameters params;
float minSize[1] = {128};
float aspectRatios[1] = {1};
params.minSize = minSize;
params.maxSize = nullptr;
params.aspectRatios = aspectRatios;
params.numMinSize = 1;
params.numMaxSize = 0;
params.numAspectRatios = 1;
params.flip = true;
params.clip = true;
params.variance[0] = 0.1;
params.variance[1] = 0.1;
params.variance[2] = 0.2;
params.variance[3] = 0.2;
params.imgH = 0;
params.imgW = 0;
params.stepH = 0;
params.stepW = 0;
params.offset = 0.5;
Inception3_conv_priorbox3_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(params));
return (nvinfer1::IPlugin*)Inception3_conv_priorbox3_layer.get();
}
else if (!strcmp(layerName,"conv6/priorbox"))
{
assert(conv6_priorbox_layer.get() == nullptr);
HiPrioxBoxParameters params;
float minSize[1] = {256};
float aspectRatios[1] = {1};
params.minSize = minSize;
params.maxSize = nullptr;
params.aspectRatios = aspectRatios;
params.numMinSize = 1;
params.numMaxSize = 0;
params.numAspectRatios = 1;
params.flip = true;
params.clip = true;
params.variance[0] = 0.1;
params.variance[1] = 0.1;
params.variance[2] = 0.2;
params.variance[3] = 0.2;
params.imgH = 0;
params.imgW = 0;
params.stepH = 0;
params.stepW = 0;
params.offset = 0.5;
conv6_priorbox_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(params));
return (nvinfer1::IPlugin*)conv6_priorbox_layer.get();
}
else if (!strcmp(layerName,"conv7/priorbox"))
{
assert(conv7_priorbox_layer.get() == nullptr);
HiPrioxBoxParameters params;
float minSize[1] = {512};
float aspectRatios[1] = {1};
params.minSize = minSize;
params.maxSize = nullptr;
params.aspectRatios = aspectRatios;
params.numMinSize = 1;
params.numMaxSize = 0;
params.numAspectRatios = 1;
params.flip = true;
params.clip = true;
params.variance[0] = 0.1;
params.variance[1] = 0.1;
params.variance[2] = 0.2;
params.variance[3] = 0.2;
params.imgH = 0;
params.imgW = 0;
params.stepH = 0;
params.stepW = 0;
params.offset = 0.5;
conv7_priorbox_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(params));
return (nvinfer1::IPlugin*)conv7_priorbox_layer.get();
}
else if (!strcmp(layerName,"detection_out"))
{
assert(mDetection_out.get() == nullptr);
plugin::DetectionOutputParameters params;
params.shareLocation = true;
params.varianceEncodedInTarget = true;
params.backgroundLabelId = 0;
params.numClasses = 2;
params.topK = 100;
params.keepTopK = 100;
params.confidenceThreshold = 0.5;
params.nmsThreshold = 0.45;
params.codeType = CodeTypeSSD::CENTER_SIZE;
params.inputOrder[0] = 0;
params.inputOrder[1] = 1;
params.inputOrder[2] = 2;
params.confSigmoid = true;
params.isNormalized = true;
mDetection_out = std::unique_ptr<nvinfer1::plugin::INvPlugin, decltype(pluginDeleter)>(plugin::createSSDDetectionOutputPlugin(params),pluginDeleter);
return mDetection_out.get();
}
else
{
std::cout << "this layer is not found :" << layerName << std::endl;
assert(0);
return nullptr;
}
}
nvinfer1::IPlugin* PluginFactory::createPlugin(const char* layerName,const void* seriaData,size_t serialLength)
{
assert(PluginFactory::isPluginExt(layerName));
if(!strcmp(layerName,"Inception3/conv/priorbox1"))
{
assert(Inception3_conv_priorbox1_layer.get() == nullptr);
Inception3_conv_priorbox1_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(seriaData,serialLength));
return (nvinfer1::IPlugin*)Inception3_conv_priorbox1_layer.get();
}
else if(!strcmp(layerName,"Inception3/conv/priorbox2"))
{
assert(Inception3_conv_priorbox2_layer.get() == nullptr);
Inception3_conv_priorbox2_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(seriaData,serialLength));
return (nvinfer1::IPlugin*)Inception3_conv_priorbox2_layer.get();
}
else if(!strcmp(layerName,"Inception3/conv/priorbox3"))
{
assert(Inception3_conv_priorbox3_layer.get() == nullptr);
Inception3_conv_priorbox3_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(seriaData,serialLength));
return (nvinfer1::IPlugin*)Inception3_conv_priorbox3_layer.get();
}
else if(!strcmp(layerName,"conv6/priorbox"))
{
assert(conv6_priorbox_layer.get() == nullptr);
conv6_priorbox_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(seriaData,serialLength));
return (nvinfer1::IPlugin*)conv6_priorbox_layer.get();
}
else if(!strcmp(layerName,"conv7/priorbox"))
{
assert(conv7_priorbox_layer.get() == nullptr);
conv7_priorbox_layer = std::unique_ptr<PriorBoxPlugin>(new PriorBoxPlugin(seriaData,serialLength));
return (nvinfer1::IPlugin*)conv7_priorbox_layer.get();
}
else if(!strcmp(layerName,"detection_out"))
{
assert(mDetection_out.get() == nullptr);
mDetection_out = std::unique_ptr<nvinfer1::plugin::INvPlugin, decltype(pluginDeleter)>(plugin::createSSDDetectionOutputPlugin(seriaData,serialLength),pluginDeleter);
return mDetection_out.get();
}
else
{
std::cout << "the layer is not exit:" << layerName << std::endl;
assert(0);
return nullptr;
}
}
bool PluginFactory::isPluginExt(const char* name)
{
return (!strcmp(name,"Inception3/conv/priorbox1")
||!strcmp(name,"Inception3/conv/priorbox2")
||!strcmp(name,"Inception3/conv/priorbox3")
||!strcmp(name,"conv6/priorbox")
||!strcmp(name,"conv7/priorbox")
||!strcmp(name,"detection_out"));
}
void PluginFactory::destroyPlugin()
{
std::cout << "==========destroyPlugin=========:" << std::endl;
Inception3_conv_priorbox1_layer.release();
Inception3_conv_priorbox1_layer = nullptr;
Inception3_conv_priorbox2_layer.release();
Inception3_conv_priorbox2_layer = nullptr;
Inception3_conv_priorbox3_layer.release();
Inception3_conv_priorbox3_layer = nullptr;
conv6_priorbox_layer.release();
conv6_priorbox_layer = nullptr;
conv7_priorbox_layer.release();
conv7_priorbox_layer = nullptr;
mDetection_out.release();
mDetection_out = nullptr;
}
by the way ,we aren’t able to run your sampleSSD successfully !!