Files
TheRock/rocm-libraries/projects/hipdnn/frontend/include/hipdnn_frontend/detail/DynamicBackendLibrary.hpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

117 lines
3.9 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
/**
* @file DynamicBackendLibrary.hpp
* @brief Runtime resolution of the hipDNN backend shared library.
*
* When the frontend is built in runtime-load mode
* (@ref HIPDNN_FRONTEND_RUNTIME_LOAD_BACKEND), backend entry points are resolved
* at first use via the cross-platform loader in @c hipdnn_data_sdk::utilities
* (`dlopen`/`dlsym` on Linux, `LoadLibrary`/`GetProcAddress` on Windows) instead
* of being linked directly. This keeps a header-only consumer from inheriting a
* hard dependency on `libhipdnn_backend.so`.
*
* The library handle is opened exactly once and shared by every entry-point
* resolver. These helpers deliberately never emit log messages: the logging
* callback itself is resolved through here during frontend logging
* initialization, so logging from this layer would re-enter the loader.
*/
#pragma once
#include <atomic>
#include <cstdio>
#include <mutex>
#include <string>
#include <hipdnn_data_sdk/Visibility.hpp>
#include <hipdnn_data_sdk/utilities/PlatformUtils.hpp>
namespace hipdnn_frontend::detail
{
/**
* @brief Return the lazily-opened handle to the hipDNN backend shared library.
*
* The library is opened on first call via `std::call_once`; the result
* (including a failure, cached as `nullptr`) is reused thereafter. On failure it
* writes directly to stderr rather than the frontend logging facility, so it is
* safe to call from the logging-initialization path.
*
* `HIPDNN_HIDDEN` gives each shared object its own handle, matching the per-SO
* isolation of the backend instance accessor.
*
* @return The library handle, or `nullptr` if the backend could not be loaded.
*/
HIPDNN_HIDDEN inline hipdnn_data_sdk::utilities::SharedLibraryHandle backendLibraryHandle()
{
static hipdnn_data_sdk::utilities::SharedLibraryHandle s_handle = nullptr;
static std::once_flag s_once;
std::call_once(s_once, [] {
try
{
const std::string libraryName
= hipdnn_data_sdk::utilities::getLibraryName("hipdnn_backend");
s_handle = hipdnn_data_sdk::utilities::openLibrary(libraryName);
}
catch(const std::exception& e)
{
// Report via stderr directly rather than the frontend logging
// facility: that callback is itself resolved through this loader, so
// logging here would re-enter it.
std::fprintf(stderr, "hipDNN: failed to load backend library: %s\n", e.what());
s_handle = nullptr;
}
catch(...)
{
std::fprintf(stderr, "hipDNN: failed to load backend library (unknown error)\n");
s_handle = nullptr;
}
});
return s_handle;
}
/**
* @brief Resolve a symbol from the already-opened backend library.
*
* Returns `nullptr` if the library could not be loaded or the symbol is not
* found. Never logs.
*/
HIPDNN_HIDDEN inline void* resolveSymbol(const char* symbolName)
{
const auto handle = backendLibraryHandle();
if(handle == nullptr)
{
return nullptr;
}
return hipdnn_data_sdk::utilities::getSymbol(handle, symbolName);
}
/**
* @brief Resolve a backend entry point on first use and cache the result.
*
* @tparam Fn Function-pointer type of the entry point.
* @param cache Per-entry-point cache (start at `nullptr`).
* @param symbolName C symbol name to resolve.
* @return The resolved function pointer, or `nullptr` if it could not be found.
*/
template <typename Fn>
HIPDNN_HIDDEN inline Fn resolveBackendSymbol(std::atomic<void*>& cache, const char* symbolName)
{
void* resolved = cache.load(std::memory_order_acquire);
if(resolved == nullptr)
{
resolved = resolveSymbol(symbolName);
if(resolved != nullptr)
{
cache.store(resolved, std::memory_order_release);
}
}
return reinterpret_cast<Fn>(resolved);
}
} // namespace hipdnn_frontend::detail