Files
TheRock/rocm-libraries/dnn-providers/hipblaslt-provider/HipblasltPlugin.cpp
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

443 lines
16 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#include <iostream>
#include <hipdnn_data_sdk/utilities/EngineNames.hpp>
#include <hipdnn_flatbuffers_sdk/flatbuffer_utilities/EngineConfigWrapper.hpp>
#include <hipdnn_flatbuffers_sdk/flatbuffer_utilities/GraphWrapper.hpp>
#include <hipdnn_plugin_sdk/EnginePluginApi.h>
#include <hipdnn_plugin_sdk/PluginApi.h>
#include <hipdnn_plugin_sdk/PluginDataTypeHelpers.hpp>
#include <hipdnn_plugin_sdk/PluginHelpers.hpp>
#include <hipdnn_plugin_sdk/PluginLastErrorManager.hpp>
#include <hipdnn_plugin_sdk/PluginLogging.hpp>
#include "EngineManager.hpp"
#include "HipblasltContainer.hpp"
#include "HipblasltHandleFactory.hpp"
#include "HipblasltPlugin.hpp"
#include "HipdnnEnginePluginExecutionContext.hpp"
#include "HipdnnEnginePluginHandle.hpp"
#include "version.h"
static const char* pluginName = "hipblaslt_plugin";
static const char* pluginVersion = HIPBLASLT_PROVIDER_VERSION_STRING;
using namespace hipdnn_plugin_sdk;
using namespace hipdnn_flatbuffers_sdk::flatbuffer_utilities;
using namespace hipblaslt_plugin;
// NOLINTNEXTLINE
thread_local char PluginLastErrorManager::s_lastError[HIPDNN_PLUGIN_ERROR_STRING_MAX_LENGTH] = "";
static std::weak_ptr<HipblasltContainer> hipblasltContainerLifecyclePtr;
extern "C" {
hipdnnPluginStatus_t hipdnnPluginGetNameImpl(const char** name)
{
LOG_API_ENTRY("name_ptr=" << static_cast<void*>(name));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(name);
*name = pluginName;
LOG_API_SUCCESS(apiName, "pluginName=" << static_cast<void*>(name));
});
}
hipdnnPluginStatus_t hipdnnPluginGetVersionImpl(const char** version)
{
LOG_API_ENTRY("versionPtr=" << static_cast<void*>(version));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(version);
*version = pluginVersion;
LOG_API_SUCCESS(apiName, "version=" << static_cast<void*>(version));
});
}
hipdnnPluginStatus_t hipdnnPluginGetTypeImpl(hipdnnPluginType_t* type)
{
LOG_API_ENTRY("typePtr=" << static_cast<void*>(type));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(type);
*type = HIPDNN_PLUGIN_TYPE_ENGINE;
LOG_API_SUCCESS(apiName, "type=" << toString(*type));
});
}
void hipdnnPluginGetLastErrorStringImpl(const char** errorStr)
{
LOG_API_ENTRY("errorStrPtr=" << static_cast<void*>(errorStr));
hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(errorStr);
*errorStr = PluginLastErrorManager::getLastError();
LOG_API_SUCCESS(apiName, "errorStr=" << static_cast<void*>(errorStr));
});
}
// Once plugins are loaded via plugin manager then logging will work for them
hipdnnPluginStatus_t hipdnnPluginSetLoggingCallbackImpl(hipdnnCallback_t callback)
{
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(callback);
hipdnn_plugin_sdk::logging::initializeCallbackLogging(pluginName, callback);
LOG_API_SUCCESS(apiName, "");
});
}
hipdnnPluginStatus_t hipdnnPluginSetLogLevelImpl(hipdnnSeverity_t level)
{
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::logging::setLogLevel(level);
LOG_API_SUCCESS(apiName, "level=" << level);
});
}
hipdnnPluginStatus_t hipdnnEnginePluginGetAllEngineIdsImpl(int64_t* engineIds,
uint32_t maxEngines,
uint32_t* numEngines)
{
LOG_API_ENTRY("engineIds=" << static_cast<void*>(engineIds) << ", maxEngines=" << maxEngines
<< ", numEngines=" << static_cast<void*>(numEngines));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
if(maxEngines != 0)
{
throwIfNull(engineIds);
}
throwIfNull(numEngines);
auto allEngineIds = std::vector<int64_t>({hipdnn_data_sdk::utilities::HIPBLASLT_ENGINE_ID});
if(allEngineIds.size() > std::numeric_limits<uint32_t>::max())
{
throw HipdnnPluginException(HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"Number of engines exceeds maximum uint32_t value.");
}
if(maxEngines == 0)
{
*numEngines = static_cast<uint32_t>(allEngineIds.size());
}
else
{
*numEngines = 0;
for(auto engineId : allEngineIds)
{
if(*numEngines == maxEngines)
{
*numEngines = static_cast<uint32_t>(allEngineIds.size());
HIPDNN_PLUGIN_LOG_INFO("Maximum number of engines reached ("
<< maxEngines
<< "), ignoring additional engines, numEngines count: "
<< *numEngines);
break;
}
engineIds[*numEngines] = engineId;
(*numEngines)++;
}
}
LOG_API_SUCCESS(apiName, "numEngines=" << *numEngines);
});
}
hipdnnPluginStatus_t hipdnnEnginePluginCreateImpl(hipdnnEnginePluginHandle_t* handle)
{
LOG_API_ENTRY("handle_ptr=" << static_cast<void*>(handle));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
hipblaslt_plugin::HipblasltHandleFactory::createHipblasltHandle(handle);
auto hipblasltContainerPtr = hipblasltContainerLifecyclePtr.lock();
if(hipblasltContainerPtr != nullptr)
{
(*handle)->hipblasltContainer = hipblasltContainerPtr;
}
else
{
static std::mutex s_hipblasltContainerMutex;
std::lock_guard<std::mutex> const lock(s_hipblasltContainerMutex);
// if we do have a race condition that results in threads getting locked, we want to
// ensure that we only create one instance. Therefore, the second thread to get
// through will just read from the weak pointer rather than create a new instance.
hipblasltContainerPtr = hipblasltContainerLifecyclePtr.lock();
if(hipblasltContainerPtr != nullptr)
{
(*handle)->hipblasltContainer = hipblasltContainerPtr;
}
else
{
(*handle)->hipblasltContainer = std::make_shared<HipblasltContainer>();
hipblasltContainerLifecyclePtr = (*handle)->hipblasltContainer;
}
}
LOG_API_SUCCESS(apiName, "createdHandle=" << static_cast<void*>(*handle));
});
}
hipdnnPluginStatus_t hipdnnEnginePluginDestroyImpl(hipdnnEnginePluginHandle_t handle)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
hipblaslt_plugin::HipblasltHandleFactory::destroyHipblasltHandle(handle);
delete handle;
handle = nullptr;
LOG_API_SUCCESS(apiName, "");
});
}
hipdnnPluginStatus_t hipdnnEnginePluginSetStreamImpl(hipdnnEnginePluginHandle_t handle,
hipStream_t stream)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", stream_id=" << static_cast<void*>(stream));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
handle->setStream(stream);
LOG_API_SUCCESS(apiName, "");
});
}
hipdnnPluginStatus_t
hipdnnEnginePluginGetApplicableEngineIdsImpl(hipdnnEnginePluginHandle_t handle,
const hipdnnPluginConstData_t* opGraph,
int64_t* engineIds,
uint32_t maxEngines,
uint32_t* numEngines)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", opGraph=" << static_cast<const void*>(opGraph) << ", engineIds="
<< static_cast<void*>(engineIds) << ", maxEngines=" << maxEngines
<< ", numEngines=" << static_cast<void*>(numEngines));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(opGraph);
if(maxEngines != 0)
{
throwIfNull(engineIds);
}
throwIfNull(numEngines);
auto& engineManager = handle->getEngineManager();
GraphWrapper const opGraphWrapper(opGraph->ptr, opGraph->size);
auto applicableEngines = engineManager.getApplicableEngineIds(*handle, opGraphWrapper);
*numEngines = 0;
for(auto& engineId : applicableEngines)
{
if(*numEngines == maxEngines)
{
*numEngines = static_cast<uint32_t>(applicableEngines.size());
HIPDNN_PLUGIN_LOG_INFO("Maximum number of engines reached ("
<< maxEngines
<< "), ignoring additional engines, numEngines count: "
<< *numEngines);
break;
}
engineIds[*numEngines] = engineId;
(*numEngines)++;
}
LOG_API_SUCCESS(apiName, "numEngines=" << *numEngines);
});
}
hipdnnPluginStatus_t hipdnnEnginePluginGetEngineDetailsImpl(hipdnnEnginePluginHandle_t handle,
int64_t engineId,
const hipdnnPluginConstData_t* opGraph,
hipdnnPluginConstData_t* engineDetails)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle) << ", engineId=" << engineId
<< ", opGraph=" << static_cast<const void*>(opGraph)
<< ", engineDetails=" << static_cast<void*>(engineDetails));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(opGraph);
throwIfNull(engineDetails);
auto& engineManager = handle->getEngineManager();
GraphWrapper const opGraphWrapper(opGraph->ptr, opGraph->size);
engineManager.getEngineDetails(*handle, opGraphWrapper, engineId, *engineDetails);
LOG_API_SUCCESS(apiName, "engineDetails->ptr=" << engineDetails->ptr);
});
}
hipdnnPluginStatus_t
hipdnnEnginePluginDestroyEngineDetailsImpl(hipdnnEnginePluginHandle_t handle,
hipdnnPluginConstData_t* engineDetails)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", engineDetails=" << static_cast<void*>(engineDetails));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(engineDetails);
throwIfNull(engineDetails->ptr);
handle->removeEngineDetailsDetachedBuffer(engineDetails->ptr);
LOG_API_SUCCESS(apiName, "engineDetails->ptr=" << engineDetails->ptr);
});
}
hipdnnPluginStatus_t
hipdnnEnginePluginGetWorkspaceSizeImpl(hipdnnEnginePluginHandle_t handle,
const hipdnnPluginConstData_t* engineConfig,
const hipdnnPluginConstData_t* opGraph,
size_t* workspaceSize)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", engineConfig=" << static_cast<const void*>(engineConfig)
<< ", opGraph=" << static_cast<const void*>(opGraph)
<< ", workspaceSize=" << static_cast<void*>(workspaceSize));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(engineConfig);
throwIfNull(opGraph);
throwIfNull(workspaceSize);
auto& engineManager = handle->getEngineManager();
EngineConfigWrapper const engineConfigWrapper(engineConfig->ptr, engineConfig->size);
GraphWrapper const opGraphWrapper(opGraph->ptr, opGraph->size);
*workspaceSize = engineManager.getWorkspaceSize(
*handle, engineConfigWrapper.engineId(), opGraphWrapper);
LOG_API_SUCCESS(apiName, "workspaceSize=" << *workspaceSize);
});
}
hipdnnPluginStatus_t hipdnnEnginePluginCreateExecutionContextImpl(
hipdnnEnginePluginHandle_t handle,
const hipdnnPluginConstData_t* engineConfig,
const hipdnnPluginConstData_t* opGraph,
hipdnnEnginePluginExecutionContext_t* executionContext)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", engineConfig=" << static_cast<const void*>(engineConfig)
<< ", opGraph=" << static_cast<const void*>(opGraph)
<< ", executionContext=" << static_cast<void*>(executionContext));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(engineConfig);
throwIfNull(opGraph);
throwIfNull(executionContext);
GraphWrapper const opGraphWrapper(opGraph->ptr, opGraph->size);
EngineConfigWrapper const engineConfigWrapper(engineConfig->ptr, engineConfig->size);
auto& engineManager = handle->getEngineManager();
auto context = new HipdnnEnginePluginExecutionContext;
try
{
engineManager.initializeExecutionContext(
*handle, opGraphWrapper, engineConfigWrapper, *context);
}
catch(...)
{
delete context;
throw;
}
*executionContext = context;
LOG_API_SUCCESS(apiName,
"created_execution_context=" << static_cast<void*>(*executionContext));
});
}
hipdnnPluginStatus_t hipdnnEnginePluginDestroyExecutionContextImpl(
hipdnnEnginePluginHandle_t handle, hipdnnEnginePluginExecutionContext_t executionContext)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", executionContext=" << static_cast<void*>(executionContext));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(executionContext);
delete executionContext;
LOG_API_SUCCESS(apiName, "destroyed executionContext");
});
}
hipdnnPluginStatus_t hipdnnEnginePluginGetWorkspaceSizeFromExecutionContextImpl(
hipdnnEnginePluginHandle_t handle,
hipdnnEnginePluginExecutionContext_t executionContext,
size_t* workspaceSize)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", executionContext=" << static_cast<const void*>(executionContext)
<< ", workspaceSize=" << static_cast<void*>(workspaceSize));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(executionContext);
throwIfNull(workspaceSize);
*workspaceSize = executionContext->plan().getWorkspaceSize(*handle);
LOG_API_SUCCESS(apiName, "workspaceSize=" << *workspaceSize);
});
}
hipdnnPluginStatus_t
hipdnnEnginePluginExecuteOpGraphImpl(hipdnnEnginePluginHandle_t handle,
hipdnnEnginePluginExecutionContext_t executionContext,
void* workspace,
const hipdnnPluginDeviceBuffer_t* deviceBuffers,
uint32_t numDeviceBuffers)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle) << ", executionContext="
<< static_cast<void*>(executionContext) << ", workspace=" << workspace
<< ", deviceBuffers=" << static_cast<const void*>(deviceBuffers)
<< ", numDeviceBuffers=" << numDeviceBuffers);
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
throwIfNull(handle);
throwIfNull(executionContext);
throwIfNull(deviceBuffers);
executionContext->plan().execute(*handle, deviceBuffers, numDeviceBuffers, workspace);
LOG_API_SUCCESS(apiName, "executed graph");
});
}
} // extern "C"