diff --git a/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.cc b/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.cc index dcac36ae90e..923b30c6b9b 100644 --- a/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.cc +++ b/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.cc @@ -49,6 +49,20 @@ int TensorRTDelegate::Init() { if (!IsHardwareSupport()) { return RET_NOT_SUPPORT; } + std::vector> device_list = context_->MutableDeviceInfo(); + auto iter = std::find_if(device_list.begin(), device_list.end(), [](std::shared_ptr device) { + return device->GetDeviceType() == DeviceType::kGPU; + }); + if (iter == device_list.end()) { + MS_LOG(ERROR) << "no gpu device info found for TensorRT."; + return RET_ERROR; + } + auto gpu_info = (*iter)->Cast(); + if (gpu_info == nullptr) { + MS_LOG(ERROR) << "no gpu device info found for TensorRT."; + return RET_ERROR; + } + device_info_ = gpu_info; op_func_lists_.clear(); op_func_lists_ = { {schema::PrimitiveType_Activation, GetTensorRTOp}, @@ -132,7 +146,7 @@ TensorRTSubGraph *TensorRTDelegate::CreateTensorRTGraph(const std::vector(ops, model, from, end); auto out_tensors = GraphOutTensors(ops, model, from, end); - auto *tensorrt_graph = new (std::nothrow) TensorRTSubGraph(ops, in_tensors, out_tensors); + auto *tensorrt_graph = new (std::nothrow) TensorRTSubGraph(ops, in_tensors, out_tensors, context_, device_info_); if (tensorrt_graph == nullptr) { MS_LOG(ERROR) << "new tensorrt_graph failed."; return nullptr; diff --git a/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.h b/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.h index 26d6c7dc9d7..05d6886608b 100644 --- a/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.h +++ b/mindspore/lite/src/delegate/tensorrt/tensorrt_delegate.h @@ -18,11 +18,13 @@ #include #include #include +#include #include "include/api/delegate.h" #include "src/delegate/tensorrt/tensorrt_subgraph.h" #include "include/api/kernel.h" #include "include/errorcode.h" #include "src/common/log_adapter.h" +#include "include/api/context.h" namespace mindspore::lite { typedef TensorRTOp *(*TensorRTGetOp)(const schema::Primitive *primitive, @@ -31,7 +33,7 @@ typedef TensorRTOp *(*TensorRTGetOp)(const schema::Primitive *primitive, class TensorRTDelegate : public Delegate { public: - TensorRTDelegate() = default; + explicit TensorRTDelegate(mindspore::Context *context) : context_(context) {} ~TensorRTDelegate() override = default; @@ -46,6 +48,10 @@ class TensorRTDelegate : public Delegate { KernelIter end); std::map op_func_lists_; + + mindspore::Context *context_; + + std::shared_ptr device_info_{nullptr}; }; } // namespace mindspore::lite #endif // MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_TENSORRT_DELEGATE_ diff --git a/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.cc b/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.cc index 1dfa5f4e2ab..5be6e804a76 100644 --- a/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.cc +++ b/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.cc @@ -15,6 +15,7 @@ */ #include "src/delegate/tensorrt/tensorrt_subgraph.h" +#include #include #include #include @@ -30,9 +31,9 @@ TensorRTSubGraph::~TensorRTSubGraph() { config_->destroy(); config_ = nullptr; } - if (context_ != nullptr) { - context_->destroy(); - context_ = nullptr; + if (trt_context_ != nullptr) { + trt_context_->destroy(); + trt_context_ = nullptr; } if (engine_ != nullptr) { engine_->destroy(); @@ -74,9 +75,6 @@ int TensorRTSubGraph::BuildEngine() { MS_LOG(ERROR) << "create builder config failed."; return RET_ERROR; } - // config setup - // setMaxWorkspaceSize to x MB - this->config_->setMaxWorkspaceSize(16 * (1 << 20)); // print all network ops MS_LOG(INFO) << "build engine for tensorrt network: " << this->network_->getName(); for (int i = 0; i < this->network_->getNbLayers(); i++) { @@ -84,6 +82,9 @@ int TensorRTSubGraph::BuildEngine() { } MS_LOG(DEBUG) << "end of tensorrt network: " << this->network_->getName(); + if (SetDeviceConfig() != RET_OK) { + MS_LOG(WARNING) << "set tensorrt config failed."; + } engine_ = runtime_->GetBuilder()->buildEngineWithConfig(*this->network_, *this->config_); if (engine_ == nullptr) { MS_LOG(ERROR) << "Create engine failed in TensorRT network"; @@ -92,6 +93,43 @@ int TensorRTSubGraph::BuildEngine() { return RET_OK; } +int TensorRTSubGraph::SetDeviceConfig() { + // set fp16 + if (device_info_->GetEnableFP16() && SupportFP16()) { + config_->setFlag(nvinfer1::BuilderFlag::kFP16); + } + + // config setMaxWorkspaceSize to x MB + config_->setMaxWorkspaceSize(256 * (1 << 20)); + return RET_OK; +} + +bool TensorRTSubGraph::SupportFP16() { + int deviceCnt = 0; + + cudaError ret = cudaGetDeviceCount(&deviceCnt); + if (ret != cudaSuccess) { + MS_LOG(ERROR) << "cudaGetDeviceCount failed."; + return false; + } + std::vector supportFP16_versions{"5.3", "6.0", "6.2", "7.0", "7.2", "7.5", "8.0", "8.6"}; + cudaDeviceProp prop; + std::string version; + for (int dev = 0; dev < deviceCnt; dev++) { + ret = cudaGetDeviceProperties(&prop, dev); + if (ret != cudaSuccess) { + MS_LOG(ERROR) << "cuDeviceGetAttribute failed."; + return false; + } + version = std::to_string(prop.major) + "." + std::to_string(prop.minor); + if (std::find(supportFP16_versions.begin(), supportFP16_versions.end(), version) != supportFP16_versions.end()) { + MS_LOG(INFO) << "cuda device version is: " << version << ", support FP16, set enable FP16 tag successful"; + return true; + } + } + MS_LOG(WARNING) << "cuda device version is: " << version << ", don't support FP16, set enable FP16 tag failed"; + return false; +} int TensorRTSubGraph::BuildTensorRTGraph() { MS_ASSERT(!all_ops_.empty()); // Connect NetWork. @@ -163,8 +201,8 @@ int TensorRTSubGraph::Prepare() { MS_LOG(ERROR) << "engine_ is null in this builder_"; return RET_ERROR; } - this->context_ = this->engine_->createExecutionContext(); - if (this->context_ == nullptr) { + this->trt_context_ = this->engine_->createExecutionContext(); + if (this->trt_context_ == nullptr) { MS_LOG(ERROR) << "TensorRTSubGraph create context failed."; return RET_ERROR; } @@ -196,7 +234,7 @@ int TensorRTSubGraph::Execute() { for (size_t i = 0; i < inputs_.size(); i++) { runtime_->GetAllocator()->SyncMemInHostAndDevice(inputs_[i], trt_in_tensor_name_[i], true); } - auto ret = this->context_->executeV2(tensor_bindings_); + auto ret = this->trt_context_->executeV2(tensor_bindings_); if (!ret) { MS_LOG(ERROR) << "TensorRT execute failed."; return RET_ERROR; diff --git a/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.h b/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.h index 1ea628e093e..e50248e6760 100644 --- a/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.h +++ b/mindspore/lite/src/delegate/tensorrt/tensorrt_subgraph.h @@ -19,9 +19,11 @@ #include #include #include +#include #include "include/api/kernel.h" #include "src/delegate/tensorrt/tensorrt_runtime.h" #include "src/delegate/tensorrt/tensorrt_utils.h" +#include "include/api/context.h" namespace mindspore::lite { using mindspore::lite::RET_ERROR; @@ -29,8 +31,9 @@ using mindspore::lite::RET_OK; class TensorRTSubGraph : public kernel::Kernel { public: TensorRTSubGraph(std::vector ops, const std::vector &inputs, - const std::vector &outputs) - : kernel::Kernel(inputs, outputs, nullptr, nullptr), all_ops_(std::move(ops)) { + const std::vector &outputs, const mindspore::Context *ctx, + std::shared_ptr device_info) + : kernel::Kernel(inputs, outputs, nullptr, ctx), all_ops_(std::move(ops)), device_info_(device_info) { trt_specific_weight_nodes_ = { schema::PrimitiveType_Conv2DFusion, schema::PrimitiveType_ReduceFusion, schema::PrimitiveType_Transpose, schema::PrimitiveType_Gather, schema::PrimitiveType_Reshape, schema::PrimitiveType_PowFusion, @@ -55,6 +58,10 @@ class TensorRTSubGraph : public kernel::Kernel { private: int BuildEngine(); + int SetDeviceConfig(); + + bool SupportFP16(); + static nvinfer1::ITensor *FindTensorRTInputs(TensorRTOp *cur_op, mindspore::MSTensor in_tensor); TensorRTRuntime *runtime_{nullptr}; @@ -66,6 +73,7 @@ class TensorRTSubGraph : public kernel::Kernel { std::vector out_ops_{}; void **tensor_bindings_{nullptr}; + std::shared_ptr device_info_{nullptr}; std::set trt_specific_weight_nodes_; @@ -76,7 +84,7 @@ class TensorRTSubGraph : public kernel::Kernel { nvinfer1::INetworkDefinition *network_{nullptr}; nvinfer1::IBuilderConfig *config_{nullptr}; nvinfer1::ICudaEngine *engine_{nullptr}; - nvinfer1::IExecutionContext *context_{nullptr}; + nvinfer1::IExecutionContext *trt_context_{nullptr}; }; } // namespace mindspore::lite #endif // MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_TENSORRT_SUB_GTAPH_ diff --git a/mindspore/lite/src/lite_session.cc b/mindspore/lite/src/lite_session.cc index 488fadd1f03..f52f040ea57 100644 --- a/mindspore/lite/src/lite_session.cc +++ b/mindspore/lite/src/lite_session.cc @@ -653,6 +653,12 @@ int LiteSession::Init(const Context *context) { if (context->delegate != nullptr) { delegate_ = context->delegate; } + ms_context_ = MSContextFromContext(context); + if (ms_context_ == nullptr) { + MS_LOG(ERROR) << "transfer context to ms context failed."; + is_running_.store(false); + return RET_NULL_PTR; + } #if SUPPORT_NPU if (delegate_ == nullptr && context_->IsNpuEnabled()) { delegate_ = std::shared_ptr(new (std::nothrow) NPUDelegate(context_->GetNpuInfo())); @@ -664,7 +670,7 @@ int LiteSession::Init(const Context *context) { #endif #if GPU_TENSORRT if (delegate_ == nullptr && context_->IsGpuEnabled()) { - delegate_ = std::shared_ptr(new (std::nothrow) TensorRTDelegate()); + delegate_ = std::shared_ptr(new (std::nothrow) TensorRTDelegate(ms_context_)); if (delegate_ == nullptr) { MS_LOG(ERROR) << "New tensorrt delegate_ failed"; return RET_ERROR; @@ -694,12 +700,6 @@ int LiteSession::Init(const Context *context) { is_running_.store(false); return ret; } - ms_context_ = MSContextFromContext(context); - if (ms_context_ == nullptr) { - MS_LOG(ERROR) << "transfer context to ms context failed."; - is_running_.store(false); - return RET_NULL_PTR; - } is_running_.store(false); return RET_OK; }