Files
ANSCORE/core/ANSLibsLoader/ANSLibsLoader.cpp

107 lines
5.7 KiB
C++
Raw Normal View History

2026-03-28 16:54:11 +11:00
// ============================================================================
// ANSLibsLoader.cpp — Master orchestrator for all dynamic library loading
//
// Coordinates sub-loaders in the correct dependency order:
// 1. DLL search path injection (shared directory)
// 2. OpenCV (CvLoader) — pre-loads opencv_world + companions
// 3. OpenVINO (OvLoader) — pre-loads TBB + openvino.dll
// 4. NVIDIA stack (NvDynLoader) — TRT, cuDNN, CUDA
// 5. ONNX Runtime (EPLoader) — with execution provider selection
//
// Shutdown releases everything in reverse order.
// ============================================================================
#include "ANSLibsLoader.h"
#include "DynLibUtils.h"
#include "CvLoader.h"
#include "OvLoader.h"
#include "NvDynLoader.h"
#include "EPLoader.h"
#include <iostream>
#include <mutex>
namespace ANSCENTER {
// ─────────────────────────────────────────────────────────────────────────────
// Static member definitions
// ─────────────────────────────────────────────────────────────────────────────
bool ANSLibsLoader::s_initialized = false;
static std::mutex g_masterMutex;
// ─────────────────────────────────────────────────────────────────────────────
// Initialize
// ─────────────────────────────────────────────────────────────────────────────
void ANSLibsLoader::Initialize(const std::string& shared_dir, EngineType preferred)
{
std::lock_guard<std::mutex> lock(g_masterMutex);
if (s_initialized) return;
std::cout << "==========================================================\n"
<< "ANSLibsLoader: Initializing all dynamic libraries...\n"
<< " Shared dir : " << shared_dir << "\n"
<< " Engine pref : " << static_cast<int>(preferred) << "\n"
<< "==========================================================" << std::endl;
// ── STEP 1: Inject shared dir into search path ───────────────────────────
// This must happen before any DLL loading so all libraries in the shared
// directory are discoverable.
DynLib::InjectDllSearchPath(shared_dir);
// ── STEP 2: Pre-load OpenCV ──────────────────────────────────────────────
// Must happen before consuming DLLs (ANSODEngine etc.) are loaded, because
// those are import-linked against opencv_world and need the DLL available.
CvLoader::Initialize(shared_dir);
// ── STEP 3: Pre-load OpenVINO + TBB ──────────────────────────────────────
// OpenVINO is used directly (ov::Core) by many projects (ANSODEngine,
// ANSLPR, ANSFR, etc.). Pre-loading ensures the DLLs from the shared
// directory are resolved before any import-linked consumer is loaded.
OvLoader::Initialize(shared_dir);
// ── STEP 4: Load NVIDIA stack ────────────────────────────────────────────
// Only attempt if the preferred engine is NVIDIA or AUTO_DETECT.
if (preferred == EngineType::NVIDIA_GPU ||
preferred == EngineType::AUTO_DETECT)
{
NvDynLoader::Initialize();
}
// ── STEP 5: Load ONNX Runtime + select execution provider ────────────────
EPLoader::Initialize(shared_dir, preferred);
s_initialized = true;
std::cout << "==========================================================\n"
<< "ANSLibsLoader: Initialization complete.\n"
<< "==========================================================" << std::endl;
}
// ─────────────────────────────────────────────────────────────────────────────
// Shutdown
// ─────────────────────────────────────────────────────────────────────────────
void ANSLibsLoader::Shutdown()
{
std::lock_guard<std::mutex> lock(g_masterMutex);
// Shut down in reverse initialization order.
// Each sub-loader is idempotent and safe to call even if not initialized.
EPLoader::Shutdown();
NvDynLoader::Shutdown();
OvLoader::Shutdown();
CvLoader::Shutdown();
s_initialized = false;
}
// ─────────────────────────────────────────────────────────────────────────────
// IsInitialized
// ─────────────────────────────────────────────────────────────────────────────
bool ANSLibsLoader::IsInitialized()
{
return s_initialized;
}
} // namespace ANSCENTER