Skip to content

Commit aa12c3d

Browse files
authored
4.1: Added support for fixed batch size > 1 (cyrusbehr#39)
* Added support for fixed size batch > 1 * Added to readme
1 parent 65a37f7 commit aa12c3d

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ If this project was helpful to you, I would appreciate if you could give it a st
159159

160160
### Changelog
161161

162+
**V4.1**
163+
164+
- Added support for fixed batch size > 1.
165+
162166
**V4.0**
163167

164168
- Added support for INT8 precision.

src/engine.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,17 @@ bool Engine::build(std::string onnxModelPath, const std::array<float, 3>& subVal
104104
}
105105

106106
// Check to see if the model supports dynamic batch size or not
107+
bool doesSupportDynamicBatch = false;
107108
if (input0Batch == -1) {
109+
doesSupportDynamicBatch = true;
108110
std::cout << "Model supports dynamic batch size" << std::endl;
109-
} else if (input0Batch == 1) {
110-
std::cout << "Model only supports fixed batch size of 1" << std::endl;
111+
} else {
112+
std::cout << "Model only supports fixed batch size of " << input0Batch << std::endl;
111113
// If the model supports a fixed batch size, ensure that the maxBatchSize and optBatchSize were set correctly.
112114
if (m_options.optBatchSize != input0Batch || m_options.maxBatchSize != input0Batch) {
113-
throw std::runtime_error("Error, model only supports a fixed batch size of 1. Must set Options.optBatchSize and Options.maxBatchSize to 1");
115+
throw std::runtime_error("Error, model only supports a fixed batch size of " + std::to_string(input0Batch) +
116+
". Must set Options.optBatchSize and Options.maxBatchSize to 1");
114117
}
115-
} else {
116-
throw std::runtime_error("Implementation currently only supports dynamic batch sizes or a fixed batch size of 1 (your batch size is fixed to "
117-
+ std::to_string(input0Batch) + ")");
118118
}
119119

120120
auto config = std::unique_ptr<nvinfer1::IBuilderConfig>(builder->createBuilderConfig());
@@ -134,7 +134,11 @@ bool Engine::build(std::string onnxModelPath, const std::array<float, 3>& subVal
134134
int32_t inputW = inputDims.d[3];
135135

136136
// Specify the optimization profile`
137-
optProfile->setDimensions(inputName, OptProfileSelector::kMIN, Dims4(1, inputC, inputH, inputW));
137+
if (doesSupportDynamicBatch) {
138+
optProfile->setDimensions(inputName, OptProfileSelector::kMIN, Dims4(1, inputC, inputH, inputW));
139+
} else {
140+
optProfile->setDimensions(inputName, OptProfileSelector::kMIN, Dims4(m_options.optBatchSize, inputC, inputH, inputW));
141+
}
138142
optProfile->setDimensions(inputName, OptProfileSelector::kOPT, Dims4(m_options.optBatchSize, inputC, inputH, inputW));
139143
optProfile->setDimensions(inputName, OptProfileSelector::kMAX, Dims4(m_options.maxBatchSize, inputC, inputH, inputW));
140144
}
@@ -267,6 +271,7 @@ bool Engine::loadNetwork() {
267271

268272
// Store the input dims for later use
269273
m_inputDims.emplace_back(tensorShape.d[1], tensorShape.d[2], tensorShape.d[3]);
274+
m_inputBatchSize = tensorShape.d[0];
270275
} else if (tensorType == TensorIOMode::kOUTPUT) {
271276
// The binding is an output
272277
uint32_t outputLenFloat = 1;
@@ -316,6 +321,15 @@ bool Engine::runInference(const std::vector<std::vector<cv::cuda::GpuMat>> &inpu
316321
return false;
317322
}
318323

324+
// Ensure that if the model has a fixed batch size that is greater than 1, the input has the correct length
325+
if (m_inputBatchSize != -1 && inputs[0].size() != static_cast<size_t>(m_inputBatchSize)) {
326+
std::cout << "===== Error =====" << std::endl;
327+
std::cout << "The batch size is different from what the model expects!" << std::endl;
328+
std::cout << "Model batch size: " << m_inputBatchSize << std::endl;
329+
std::cout << "Batch size provided to call to runInference: " << inputs[0].size() << std::endl;
330+
return false;
331+
}
332+
319333
const auto batchSize = static_cast<int32_t>(inputs[0].size());
320334
// Make sure the same batch size was provided for all inputs
321335
for (size_t i = 1; i < inputs.size(); ++i) {

src/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class Engine {
162162
std::vector<nvinfer1::Dims3> m_inputDims;
163163
std::vector<nvinfer1::Dims> m_outputDims;
164164
std::vector<std::string> m_IOTensorNames;
165+
int32_t m_inputBatchSize;
165166

166167
// Must keep IRuntime around for inference, see: https://forums.developer.nvidia.com/t/is-it-safe-to-deallocate-nvinfer1-iruntime-after-creating-an-nvinfer1-icudaengine-but-before-running-inference-with-said-icudaengine/255381/2?u=cyruspk4w6
167168
std::unique_ptr<nvinfer1::IRuntime> m_runtime = nullptr;

src/main.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ int main(int argc, char *argv[]) {
3131
options.precision = Precision::FP16;
3232
// If using INT8 precision, must specify path to directory containing calibration data.
3333
options.calibrationDataDirectoryPath = "";
34-
// If the model does not support dynamic batch size, then the below two parameters must be set to 1.
3534
// Specify the batch size to optimize for.
3635
options.optBatchSize = 1;
3736
// Specify the maximum batch size we plan on running.

0 commit comments

Comments
 (0)