@@ -28,11 +28,24 @@ extern TensorrtLogger& GetTensorrtLogger(bool verbose);
2828 * So, TensorRTCustomOp uses variadic inputs/outputs to pass ONNX graph validation.
2929 */
3030common::Status CreateTensorRTCustomOpDomainList (std::vector<OrtCustomOpDomain*>& domain_list, const std::string extra_plugin_lib_paths) {
31+ // Domain for TRT plugin custom ops (domain name: "trt.plugins"). Owns the OrtCustomOpDomain object.
32+ // Raw pointers from .get() are handed out to callers via domain_list and may be held by InferenceSession.
3133 static std::unique_ptr<OrtCustomOpDomain> custom_op_domain = std::make_unique<OrtCustomOpDomain>();
34+
35+ // Owns the TensorRTCustomOp objects for TRT plugins. Raw pointers are stored in custom_op_domain->custom_ops_.
3236 static std::vector<std::unique_ptr<TensorRTCustomOp>> created_custom_op_list;
37+
38+ // Domain for native custom ops (domain name: "trt"). Owns the OrtCustomOpDomain object.
39+ // Raw pointers from .get() are handed out to callers via domain_list and may be held by InferenceSession.
3340 static std::unique_ptr<OrtCustomOpDomain> native_custom_op_domain = std::make_unique<OrtCustomOpDomain>();
41+
42+ // Owns the TensorRTCustomOp objects for native custom ops. Raw pointers are stored in native_custom_op_domain->custom_ops_.
3443 static std::vector<std::unique_ptr<TensorRTCustomOp>> native_custom_op_list;
44+
45+ // Tracks whether native custom ops have been registered to avoid re-registration on subsequent calls.
3546 static bool native_custom_ops_initialized = false ;
47+
48+ // Protects concurrent access to all the above static members.
3649 static std::mutex mutex;
3750 std::lock_guard<std::mutex> lock (mutex);
3851
@@ -138,9 +151,9 @@ common::Status CreateTensorRTCustomOpDomainList(std::vector<OrtCustomOpDomain*>&
138151 // Register native custom ops (register these independent of TRT plugin library availability)
139152 if (!native_custom_ops_initialized) {
140153 const char * native_custom_ops_names[] = {" TRT_FP4DynamicQuantize" , " TRT_FP8QuantizeLinear" , " TRT_FP8DequantizeLinear" };
141- int num_native_custom_ops = std::size (native_custom_ops_names);
154+ size_t num_native_custom_ops = std::size (native_custom_ops_names);
142155
143- for (int i = 0 ; i < num_native_custom_ops; i++) {
156+ for (size_t i = 0 ; i < num_native_custom_ops; i++) {
144157 native_custom_op_list.push_back (std::make_unique<TensorRTCustomOp>(onnxruntime::kNvTensorRTRTXExecutionProvider , nullptr ));
145158 native_custom_op_list.back ()->SetName (native_custom_ops_names[i]);
146159 native_custom_op_domain->custom_ops_ .push_back (native_custom_op_list.back ().get ());
@@ -156,9 +169,12 @@ common::Status CreateTensorRTCustomOpDomainList(std::vector<OrtCustomOpDomain*>&
156169
157170void ReleaseTensorRTCustomOpDomain (OrtCustomOpDomain* domain) {
158171 (void )domain; // Suppress unused parameter warning
159- // The custom ops (TensorRTCustomOp) and domain (OrtCustomOpDomain) are marked as static
160- // with unique_ptr at the time of creation in CreateTensorRTCustomOpDomainList() function.
161- // Deleting them here can risk double-delete.
172+ // The domain and its custom ops are owned by static unique_ptrs in CreateTensorRTCustomOpDomainList().
173+ // Callers receive raw pointers via .get().
174+ // 1. Manually deleting them would cause a double-free when the static unique_ptrs are destroyed at program exit.
175+ // 2. Resetting the static unique_ptrs is also unsafe because other EP instances or InferenceSession objects
176+ // may still hold raw pointers to these same objects (handed out via domain_list).
177+ // The static objects would be shared across EP instances and would persist for the program lifetime.
162178}
163179
164180void ReleaseTensorRTCustomOpDomainList (std::vector<OrtCustomOpDomain*>& custom_op_domain_list) {
0 commit comments