diff --git a/engines/TensorRTAPI/include/engine/EngineBuildLoadNetwork.inl b/engines/TensorRTAPI/include/engine/EngineBuildLoadNetwork.inl index c9797d4..09893ca 100644 --- a/engines/TensorRTAPI/include/engine/EngineBuildLoadNetwork.inl +++ b/engines/TensorRTAPI/include/engine/EngineBuildLoadNetwork.inl @@ -2411,6 +2411,12 @@ bool Engine::buildWithRetry(std::string onnxModelPath, const std::array& divVals, bool normalize) { + ANS_DBG("TRT_Build", "buildWithRetry ENTRY onnx=%s normalize=%d optMaxHW=%dx%d optOptHW=%dx%d optMinHW=%dx%d", + onnxModelPath.c_str(), (int)normalize, + m_options.maxInputHeight, m_options.maxInputWidth, + m_options.optInputHeight, m_options.optInputWidth, + m_options.minInputHeight, m_options.minInputWidth); + // -- Quick pre-analysis: detect dynamic spatial dims in ONNX --------------- bool hasDynamicSpatial = false; int onnxFixedH = 0, onnxFixedW = 0; // 0 = dynamic (-1 in ONNX) @@ -2423,6 +2429,10 @@ bool Engine::buildWithRetry(std::string onnxModelPath, nvonnxparser::createParser(*tempNetwork, m_logger)); std::ifstream onnxFile(onnxModelPath, std::ios::binary | std::ios::ate); + if (!onnxFile.good()) { + ANS_DBG("TRT_Build", "buildWithRetry WARN cannot open ONNX for pre-parse path=%s", + onnxModelPath.c_str()); + } if (onnxFile.good()) { std::streamsize onnxSize = onnxFile.tellg(); onnxFile.seekg(0, std::ios::beg); @@ -2432,6 +2442,8 @@ bool Engine::buildWithRetry(std::string onnxModelPath, bool retryParsed = parseOnnxModelSafe(tempParser.get(), onnxBuffer.data(), onnxBuffer.size(), &sehRetryParse); if (sehRetryParse != 0) { + ANS_DBG("TRT_Build", "buildWithRetry WARN SEH=0x%lx during pre-parse — fall through to single build()", + sehRetryParse); // hasDynamicSpatial stays false → single build() attempt } else if (retryParsed && tempNetwork->getNbInputs() > 0) { @@ -2441,19 +2453,39 @@ bool Engine::buildWithRetry(std::string onnxModelPath, hasDynamicSpatial = true; onnxFixedH = (dims.d[2] != -1) ? dims.d[2] : 0; onnxFixedW = (dims.d[3] != -1) ? dims.d[3] : 0; + ANS_DBG("TRT_Build", "buildWithRetry pre-parse OK nbDims=%d dims=[%d,%d,%d,%d] dynSpatial=%d fixedHW=%dx%d", + dims.nbDims, + (int)dims.d[0], (int)dims.d[1], (int)dims.d[2], (int)dims.d[3], + (int)hasDynamicSpatial, onnxFixedH, onnxFixedW); + } else { + ANS_DBG("TRT_Build", "buildWithRetry WARN nbDims=%d (<4) — treating as fixed", dims.nbDims); } + } else { + ANS_DBG("TRT_Build", "buildWithRetry WARN parse failed or no inputs (parsed=%d nbInputs=%d)", + (int)retryParsed, + retryParsed ? tempNetwork->getNbInputs() : -1); } + } else { + ANS_DBG("TRT_Build", "buildWithRetry WARN ONNX read failed bytes=%zd", + (long long)onnxSize); } } + } else { + ANS_DBG("TRT_Build", "buildWithRetry SKIP pre-parse (maxInputHW=%dx%d not both >0)", + m_options.maxInputHeight, m_options.maxInputWidth); } // -- Fixed-spatial or no dynamic dims: single build attempt ---------------- if (!hasDynamicSpatial) { + ANS_DBG("TRT_Build", "buildWithRetry FIXED_SPATIAL → single buildSafe() attempt"); unsigned long sehBuild = 0; bool ok = buildSafe(onnxModelPath, subVals, divVals, normalize, &sehBuild); if (sehBuild != 0) { + ANS_DBG("TRT_Build", "buildWithRetry FAIL fixed-spatial SEH=0x%lx", sehBuild); return false; } + ANS_DBG("TRT_Build", "buildWithRetry %s fixed-spatial", + ok ? "SUCCESS" : "FAIL"); return ok; } @@ -2482,6 +2514,16 @@ bool Engine::buildWithRetry(std::string onnxModelPath, if (candidates.back() > 640) candidates.push_back(640); if (candidates.back() > 320) candidates.push_back(320); + { + std::ostringstream oss; + for (size_t i = 0; i < candidates.size(); ++i) { + if (i) oss << ","; + oss << candidates[i]; + } + ANS_DBG("TRT_Build", "buildWithRetry DYNAMIC_SPATIAL dynH=%d dynW=%d maxDynDim=%d candidates=[%s]", + (int)dynamicH, (int)dynamicW, maxDynDim, oss.str().c_str()); + } + // Helper: configure m_options for a given candidate auto setCandidateOptions = [&](int candidate) { float scale = static_cast(candidate) / maxDynDim; @@ -2506,16 +2548,28 @@ bool Engine::buildWithRetry(std::string onnxModelPath, for (size_t attempt = 0; attempt < candidates.size(); ++attempt) { setCandidateOptions(candidates[attempt]); + ANS_DBG("TRT_Build", "buildWithRetry ATTEMPT %zu/%zu candidate=%d maxHW=%dx%d optHW=%dx%d minHW=%dx%d", + attempt + 1, candidates.size(), candidates[attempt], + m_options.maxInputHeight, m_options.maxInputWidth, + m_options.optInputHeight, m_options.optInputWidth, + m_options.minInputHeight, m_options.minInputWidth); + { unsigned long sehAttempt = 0; bool attemptOk = buildSafe(onnxModelPath, subVals, divVals, normalize, &sehAttempt); if (sehAttempt != 0) { + ANS_DBG("TRT_Build", "buildWithRetry FAIL SEH=0x%lx on candidate=%d — abort (CUDA may be corrupted)", + sehAttempt, candidates[attempt]); // CUDA context may be corrupted — no point retrying return false; } if (attemptOk) { + ANS_DBG("TRT_Build", "buildWithRetry SUCCESS at attempt %zu/%zu candidate=%d (final maxHW=%dx%d)", + attempt + 1, candidates.size(), candidates[attempt], + m_options.maxInputHeight, m_options.maxInputWidth); return true; } + ANS_DBG("TRT_Build", "buildWithRetry attempt %zu FAILED — trying smaller", attempt + 1); } } @@ -2527,6 +2581,8 @@ bool Engine::buildWithRetry(std::string onnxModelPath, m_options.minInputHeight = origMinH; m_options.minInputWidth = origMinW; + ANS_DBG("TRT_Build", "buildWithRetry FAIL all %zu candidates exhausted — restored origMaxHW=%dx%d", + candidates.size(), origMaxH, origMaxW); return false; } @@ -2553,6 +2609,9 @@ bool Engine::buildLoadNetwork( int maxSlotsPerGpu, double memSafetyFactor) { + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) ENTRY onnx=%s normalize=%d maxSlotsPerGpu=%d memSafety=%.3f", + onnxModelPath.c_str(), (int)normalize, maxSlotsPerGpu, memSafetyFactor); + // Force single-GPU when: maxSlotsPerGpu==0 (optimizer bypass), // per-instance forceNoPool, global bypass (OptimizeModelStr), // exported g_forceNoPool, OR single-GPU system with maxSlotsPerGpu==1. @@ -2563,18 +2622,32 @@ bool Engine::buildLoadNetwork( { extern std::atomic g_forceNoPool; int gpuCount = 0; - cudaGetDeviceCount(&gpuCount); + cudaError_t cudaErr = cudaGetDeviceCount(&gpuCount); + if (cudaErr != cudaSuccess) { + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) WARN cudaGetDeviceCount err=%d (%s) — assuming gpuCount=0", + (int)cudaErr, cudaGetErrorString(cudaErr)); + } bool singleGpuNoElastic = (gpuCount <= 1 && maxSlotsPerGpu == 1); + bool gForceNoPool = g_forceNoPool.load(std::memory_order_relaxed); + bool globalBypass = TRTEngineCache::globalBypass().load(std::memory_order_relaxed); bool noPool = (maxSlotsPerGpu == 0) || m_forceNoPool || - g_forceNoPool.load(std::memory_order_relaxed) || - TRTEngineCache::globalBypass().load(std::memory_order_relaxed) || - singleGpuNoElastic; + gForceNoPool || globalBypass || singleGpuNoElastic; + + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) DECISION gpuCount=%d maxSlots==0:%d m_forceNoPool=%d g_forceNoPool=%d globalBypass=%d singleGpuNoElastic=%d → noPool=%d", + gpuCount, (int)(maxSlotsPerGpu == 0), (int)m_forceNoPool, + (int)gForceNoPool, (int)globalBypass, (int)singleGpuNoElastic, + (int)noPool); + if (noPool) { std::cout << "Info: buildLoadNetwork -- single-GPU forced (maxSlots=" << maxSlotsPerGpu << ", forceNoPool=" << m_forceNoPool << ", g_forceNoPool=" << g_forceNoPool.load() << ", gpuCount=" << gpuCount << ")" << std::endl; - return buildLoadNetwork(onnxModelPath, subVals, divVals, normalize); + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) → single-GPU 4-param overload"); + bool ok = buildLoadNetwork(onnxModelPath, subVals, divVals, normalize); + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) %s (single-GPU path)", + ok ? "SUCCESS" : "FAIL"); + return ok; } } @@ -2583,11 +2656,16 @@ bool Engine::buildLoadNetwork( std::cout << "Info: buildLoadNetwork -- activating multi-GPU pool" << " (maxSlotsPerGpu=" << maxSlotsPerGpu << ", memSafetyFactor=" << memSafetyFactor << ")" << std::endl; + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) → loadSlots multi-GPU pool maxSlotsPerGpu=%d memSafety=%.3f", + maxSlotsPerGpu, memSafetyFactor); - return loadSlots(m_options, onnxModelPath, - subVals, divVals, normalize, - /*fromOnnx=*/true, - maxSlotsPerGpu, memSafetyFactor); + bool ok = loadSlots(m_options, onnxModelPath, + subVals, divVals, normalize, + /*fromOnnx=*/true, + maxSlotsPerGpu, memSafetyFactor); + ANS_DBG("TRT_Build", "buildLoadNetwork(6p) %s (multi-GPU pool path)", + ok ? "SUCCESS" : "FAIL"); + return ok; } template diff --git a/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp b/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp index 22a1d1b..55b9631 100644 --- a/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp +++ b/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp @@ -5,11 +5,15 @@ namespace ANSCENTER { std::string ANSCUSTOMDETECTOR::FindANSCustomLibraryName(const std::string& folderPath, const std::string& keyword) { + ANS_DBG("ANSCUSTOM_FindLib", "ENTRY folder=%s keyword=%s", + folderPath.c_str(), keyword.c_str()); std::string searchPath = folderPath + "\\*.dll"; WIN32_FIND_DATAA findFileData; HANDLE hFind = FindFirstFileA(searchPath.c_str(), &findFileData); if (hFind == INVALID_HANDLE_VALUE) { + ANS_DBG("ANSCUSTOM_FindLib", "NO_MATCH (FindFirstFile invalid handle) folder=%s", + folderPath.c_str()); return ""; // Return an empty string if no file is found } @@ -17,39 +21,68 @@ namespace ANSCENTER std::string fileName = findFileData.cFileName; if (fileName.find(keyword) != std::string::npos) { FindClose(hFind); // Close the handle before returning - return folderPath + "\\" + fileName; // Return the full path + std::string fullPath = folderPath + "\\" + fileName; + ANS_DBG("ANSCUSTOM_FindLib", "FOUND %s", fullPath.c_str()); + return fullPath; // Return the full path } } while (FindNextFileA(hFind, &findFileData) != 0); FindClose(hFind); // Close the handle after finishing the loop + ANS_DBG("ANSCUSTOM_FindLib", "NO_MATCH folder=%s keyword=%s", + folderPath.c_str(), keyword.c_str()); return ""; // Return an empty string if no match is found } bool ANSCUSTOMDETECTOR::OptimizeModel(bool fp16, std::string& optimizedModelFolder) { + ANS_DBG("ANSCUSTOM_Optimize", "ENTRY this=%p fp16=%d", (void*)this, (int)fp16); std::lock_guard lock(_mutex); if (!ANSODBase::OptimizeModel(fp16, optimizedModelFolder)) { + ANS_DBG("ANSCUSTOM_Optimize", "ERROR base OptimizeModel failed this=%p", (void*)this); return false; } optimizedModelFolder = _modelFolder; - return _customDetector->OptimizeModel(fp16); + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_Optimize", "ERROR _customDetector null this=%p", (void*)this); + return false; + } + bool ok = _customDetector->OptimizeModel(fp16); + ANS_DBG("ANSCUSTOM_Optimize", "%s this=%p folder=%s", + ok ? "SUCCESS" : "FAILED", (void*)this, optimizedModelFolder.c_str()); + return ok; } bool ANSCUSTOMDETECTOR::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) { + ANS_DBG("ANSCUSTOM_LoadModel", "ENTRY this=%p zip=%s", (void*)this, modelZipFilePath.c_str()); std::lock_guard lock(_mutex); ModelLoadingGuard mlg(_modelLoading); try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); - if (!result) return false; + if (!result) { + ANS_DBG("ANSCUSTOM_LoadModel", "ERROR base LoadModel failed this=%p zip=%s", + (void*)this, modelZipFilePath.c_str()); + return false; + } std::string labelMap; CreateCustomDetector(); + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_LoadModel", "ERROR _customDetector null after Create this=%p", (void*)this); + return false; + } //_customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation); - return _customDetector->Initialize(_modelFolder,_modelConfig.detectionScoreThreshold, labelMap); + bool ok = _customDetector->Initialize(_modelFolder,_modelConfig.detectionScoreThreshold, labelMap); + ANS_DBG("ANSCUSTOM_LoadModel", "%s this=%p folder=%s thr=%.3f", + ok ? "SUCCESS" : "FAILED", (void*)this, _modelFolder.c_str(), + _modelConfig.detectionScoreThreshold); + return ok; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_LoadModel", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::LoadModel", e.what(), __FILE__, __LINE__); return false; } } bool ANSCUSTOMDETECTOR::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) { + ANS_DBG("ANSCUSTOM_LoadFolder", "ENTRY this=%p model=%s class=%s folder=%s", + (void*)this, modelName.c_str(), className.c_str(), modelFolder.c_str()); std::lock_guard lock(_mutex); ModelLoadingGuard mlg(_modelLoading); try { @@ -61,19 +94,32 @@ namespace ANSCENTER if (_modelConfig.modelConfThreshold < 0.2) _modelConfig.modelConfThreshold = 0.5; CreateCustomDetector(); + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_LoadFolder", "ERROR _customDetector null after Create this=%p", (void*)this); + _isInitialized = false; + return false; + } _customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation); _isInitialized = _customDetector->Initialize(_modelFolder, _modelConfig.detectionScoreThreshold, labelMap); + ANS_DBG("ANSCUSTOM_LoadFolder", "%s this=%p folder=%s thr=%.3f loadOnCreate=%d", + _isInitialized ? "SUCCESS" : "FAILED", + (void*)this, _modelFolder.c_str(), + _modelConfig.detectionScoreThreshold, + (int)this->_loadEngineOnCreation); return _isInitialized; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_LoadFolder", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::LoadModel", e.what(), __FILE__, __LINE__); return false; } } bool ANSCUSTOMDETECTOR::ConfigureParameters(Params& param) { + ANS_DBG("ANSCUSTOM_Configure", "ENTRY this=%p", (void*)this); std::lock_guard lock(_mutex); try { if (!_customDetector) { + ANS_DBG("ANSCUSTOM_Configure", "ERROR _customDetector null this=%p", (void*)this); this->_logger.LogError("ANSCUSTOMDETECTOR::ConfigureParamaters", "Custom detector is not initialized", __FILE__, __LINE__); return false; } @@ -131,16 +177,27 @@ namespace ANSCENTER } param.ROI_Values.push_back(roiValue); } + ANS_DBG("ANSCUSTOM_Configure", "SUCCESS this=%p ROI_Config=%zu Options=%zu Params=%zu ROI_Values=%zu", + (void*)this, param.ROI_Config.size(), param.ROI_Options.size(), + param.Parameters.size(), param.ROI_Values.size()); return true; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_Configure", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::ConfigureParamaters", e.what(), __FILE__, __LINE__); return false; } } bool ANSCUSTOMDETECTOR::SetParameters(const Params& param) { + ANS_DBG("ANSCUSTOM_SetParams", "ENTRY this=%p ROI_Config=%zu Options=%zu Params=%zu ROI_Values=%zu", + (void*)this, param.ROI_Config.size(), param.ROI_Options.size(), + param.Parameters.size(), param.ROI_Values.size()); std::lock_guard lock(_mutex); try { + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_SetParams", "ERROR _customDetector null this=%p", (void*)this); + return false; + } // Convert the vector of Params to a vector of CustomParams ANSODBase::SetParameters(param); CustomParams customParams; @@ -193,24 +250,31 @@ namespace ANSCENTER } customParams.ROI_Values.push_back(roiValue); } - return _customDetector->SetParameters(customParams); + bool ok = _customDetector->SetParameters(customParams); + ANS_DBG("ANSCUSTOM_SetParams", "%s this=%p", ok ? "SUCCESS" : "FAILED", (void*)this); + return ok; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_SetParams", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::SetParamaters", e.what(), __FILE__, __LINE__); return false; } } bool ANSCUSTOMDETECTOR::CreateCustomDetector() { + ANS_DBG("ANSCUSTOM_CreateDet", "ENTRY this=%p folder=%s prevDet=%p prevHMod=%p", + (void*)this, _modelFolder.c_str(), + (void*)_customDetector.get(), (void*)hMod); std::lock_guard lock(_mutex); try { Destroy(); //1. Load dynamic library - _modelFilePath = FindANSCustomLibraryName(_modelFolder, "ANSCustom");// + _modelFilePath = FindANSCustomLibraryName(_modelFolder, "ANSCustom");// if (!FileExist(_modelFilePath)) { _modelFilePath = CreateFilePath(_modelFolder, "ANSCustomCode.dll"); // This is the dynamic library } //2. Check if the file exists again if (!FileExist(_modelFilePath)) { + ANS_DBG("ANSCUSTOM_CreateDet", "ERROR DLL not found path=%s", _modelFilePath.c_str()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot find ANSCustomCode.dll", __FILE__, __LINE__); return false; } @@ -219,35 +283,54 @@ namespace ANSCENTER std::wstring dllPath = String2WString(_modelFilePath); hMod = LoadLibrary(dllPath.c_str()); if (!hMod) { + DWORD err = GetLastError(); + ANS_DBG("ANSCUSTOM_CreateDet", "ERROR LoadLibrary failed path=%s err=%lu", + _modelFilePath.c_str(), (unsigned long)err); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot open library", __FILE__, __LINE__); return false; } + ANS_DBG("ANSCUSTOM_CreateDet", "LIB_LOADED hMod=%p path=%s", (void*)hMod, _modelFilePath.c_str()); CreatePluginFunc createPlugin = (CreatePluginFunc)GetProcAddress(hMod, "Create"); if (!createPlugin) { + ANS_DBG("ANSCUSTOM_CreateDet", "ERROR GetProcAddress(Create) failed hMod=%p — FreeLibrary", + (void*)hMod); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize.", "Cannot load Create", __FILE__, __LINE__); FreeLibrary(hMod); + hMod = nullptr; return false; } _customDetector = std::unique_ptr(createPlugin()); if (!_customDetector) { + ANS_DBG("ANSCUSTOM_CreateDet", "ERROR createPlugin returned null hMod=%p — FreeLibrary", + (void*)hMod); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot create custom detector", __FILE__, __LINE__); FreeLibrary(hMod); + hMod = nullptr; return false; } + ANS_DBG("ANSCUSTOM_CreateDet", "SUCCESS this=%p detector=%p hMod=%p", + (void*)this, (void*)_customDetector.get(), (void*)hMod); return true; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_CreateDet", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", e.what(), __FILE__, __LINE__); return false; } } bool ANSCUSTOMDETECTOR::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { + ANS_DBG("ANSCUSTOM_Initialize", "ENTRY this=%p zip=%s", + (void*)this, modelZipFilePath.c_str()); std::lock_guard lock(_mutex); ModelLoadingGuard mlg(_modelLoading); try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); - if (!result) return false; + if (!result) { + ANS_DBG("ANSCUSTOM_Initialize", "ERROR base Initialize failed this=%p zip=%s", + (void*)this, modelZipFilePath.c_str()); + return false; + } _modelConfig = modelConfig; if (_modelConfig.modelMNSThreshold < 0.2) _modelConfig.modelMNSThreshold = 0.5; @@ -257,12 +340,23 @@ namespace ANSCENTER labelMap.clear(); //1. Create custom detector CreateCustomDetector(); + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_Initialize", "ERROR _customDetector null after Create this=%p", (void*)this); + _isInitialized = false; + return false; + } //2. Load initial model _customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation); _isInitialized = _customDetector->Initialize(_modelFolder, _modelConfig.detectionScoreThreshold,labelMap); + ANS_DBG("ANSCUSTOM_Initialize", "%s this=%p folder=%s thr=%.3f loadOnCreate=%d", + _isInitialized ? "SUCCESS" : "FAILED", + (void*)this, _modelFolder.c_str(), + _modelConfig.detectionScoreThreshold, + (int)this->_loadEngineOnCreation); return _isInitialized; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_Initialize", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", e.what(), __FILE__, __LINE__); return false; } @@ -271,24 +365,42 @@ namespace ANSCENTER return RunInference(input, "CustomCam"); } std::vector ANSCUSTOMDETECTOR::RunInference(const cv::Mat& input,const std::string& camera_id) { - if (!PreInferenceCheck("ANSCUSTOMDETECTOR::RunInference")) return {}; + ANS_DBG("ANSCUSTOM_Infer", "ENTRY this=%p cam=%s in=%dx%d type=%d", + (void*)this, camera_id.c_str(), input.cols, input.rows, input.type()); + if (!PreInferenceCheck("ANSCUSTOMDETECTOR::RunInference")) { + ANS_DBG("ANSCUSTOM_Infer", "EARLY_OUT preInferenceCheck failed this=%p cam=%s", + (void*)this, camera_id.c_str()); + return {}; + } std::vector result; try { // Early returns - good practice maintained if (!_licenseValid) { + ANS_DBG("ANSCUSTOM_Infer", "ERROR invalid license this=%p cam=%s", + (void*)this, camera_id.c_str()); this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference", "Invalid License", __FILE__, __LINE__); return result; } if (!_isInitialized) { + ANS_DBG("ANSCUSTOM_Infer", "ERROR not initialized this=%p cam=%s", + (void*)this, camera_id.c_str()); this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference", "Model is not initialized", __FILE__, __LINE__); return result; } if (input.empty() || input.cols < 10 || input.rows < 10) { + ANS_DBG("ANSCUSTOM_Infer", "EARLY_OUT input too small this=%p cam=%s %dx%d", + (void*)this, camera_id.c_str(), input.cols, input.rows); + return result; + } + + if (!_customDetector) { + ANS_DBG("ANSCUSTOM_Infer", "ERROR _customDetector null this=%p cam=%s", + (void*)this, camera_id.c_str()); return result; } @@ -320,9 +432,14 @@ namespace ANSCENTER if (_stabilizationEnabled) result = StabilizeDetections(result, camera_id); } + ANS_DBG("ANSCUSTOM_Infer", "DONE this=%p cam=%s det=%zu tracked=%d stab=%d", + (void*)this, camera_id.c_str(), result.size(), + (int)_trackerEnabled, (int)_stabilizationEnabled); return result; // RVO applies, no copy } catch (const std::exception& e) { // Catch by const reference + ANS_DBG("ANSCUSTOM_Infer", "ERROR exception this=%p cam=%s: %s", + (void*)this, camera_id.c_str(), e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::RunInference", e.what(), __FILE__, __LINE__); return {}; // Return empty vector @@ -330,26 +447,43 @@ namespace ANSCENTER } ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR() { + ANS_DBG("ANSCUSTOM_Dtor", "ENTRY this=%p detector=%p hMod=%p", + (void*)this, (void*)_customDetector.get(), (void*)hMod); try { - //this->_logger.LogDebug("ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR()", "Release ANSCUSTOMDETECTOR ", __FILE__, __LINE__); + // Auto-release plugin object before unloading its DLL. + // Destroy() itself swallows exceptions, but wrap defensively + // so the destructor never throws. + Destroy(); } - catch (std::exception& e) { + catch (const std::exception& e) { + ANS_DBG("ANSCUSTOM_Dtor", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR()", e.what(), __FILE__, __LINE__); } + catch (...) { + ANS_DBG("ANSCUSTOM_Dtor", "ERROR unknown exception this=%p", (void*)this); + } + ANS_DBG("ANSCUSTOM_Dtor", "EXIT this=%p detector=%p hMod=%p", + (void*)this, (void*)_customDetector.get(), (void*)hMod); } bool ANSCUSTOMDETECTOR::Destroy() { + ANS_DBG("ANSCUSTOM_Destroy", "ENTRY this=%p detector=%p hMod=%p", + (void*)this, (void*)_customDetector.get(), (void*)hMod); try { if (_customDetector) { + ANS_DBG("ANSCUSTOM_Destroy", "DESTROY detector=%p", (void*)_customDetector.get()); _customDetector->Destroy(); _customDetector.reset(); } if (hMod) { + ANS_DBG("ANSCUSTOM_Destroy", "FREE_LIBRARY hMod=%p", (void*)hMod); FreeLibrary(hMod); hMod = nullptr; } + ANS_DBG("ANSCUSTOM_Destroy", "SUCCESS this=%p", (void*)this); return true; } catch (std::exception& e) { + ANS_DBG("ANSCUSTOM_Destroy", "ERROR exception this=%p: %s", (void*)this, e.what()); this->_logger.LogFatal("ANSCUSTOMDETECTOR::Destroy", e.what(), __FILE__, __LINE__); return false; }