Files
TheRock/rocm-libraries/projects/hipdnn/tests/test_plugins/TestPluginCommon.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

1260 lines
62 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#pragma once
#include <array>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <hip/hip_runtime.h>
#include <hipdnn_data_sdk/utilities/PlatformUtils.hpp>
#include <hipdnn_flatbuffers_sdk/data_objects/engine_details_generated.h>
#include <hipdnn_flatbuffers_sdk/flatbuffer_utilities/EngineConfigWrapper.hpp>
#include <hipdnn_flatbuffers_sdk/flatbuffer_utilities/GraphWrapper.hpp>
#include <hipdnn_plugin_sdk/BehaviorNote.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 <hipdnn_plugin_sdk/version.h>
struct HipdnnEnginePluginHandle
{
public:
virtual ~HipdnnEnginePluginHandle() = default;
};
struct HipdnnEnginePluginExecutionContext
{
// Engine ID captured at execution-context creation. Lets a plugin make
// per-engine execution decisions (e.g. an engine that fails on purpose).
int64_t engineId = 0;
// True if global.benchmarking=1 was set in the engine config knob settings.
// Used by autotune test plugins to simulate priming-only failures.
bool hasBenchmarkingKnobEnabled = false;
};
inline const char* apiVersionWithoutTweak()
{
static const std::string s_versionStr = std::to_string(HIPDNN_PLUGIN_SDK_VERSION_MAJOR) + "."
+ std::to_string(HIPDNN_PLUGIN_SDK_VERSION_MINOR) + "."
+ std::to_string(HIPDNN_PLUGIN_SDK_VERSION_PATCH);
return s_versionStr.c_str();
}
/// Execute entry point most recently serviced by a fake plugin.
enum class TestPluginExecuteEntry : uint8_t
{
NONE = 0,
OP_GRAPH = 1, ///< hipdnnEnginePluginExecuteOpGraph was called.
OP_GRAPH_WITH_OVERRIDES = 2, ///< hipdnnEnginePluginExecuteOpGraphWithOverrides was called.
};
inline constexpr std::size_t K_MAX_TEST_OVERRIDES = 8;
inline constexpr std::size_t K_MAX_TEST_OVERRIDE_RANK = 8;
using TestPluginSerializedContextPayload = std::array<uint8_t, 1>;
struct TestPluginFreeDeleter
{
void operator()(const void* ptr) const
{
std::free(const_cast<void*>(ptr));
}
};
using TestPluginMallocBuffer = std::unique_ptr<void, TestPluginFreeDeleter>;
using TestPluginConstMallocBuffer = std::unique_ptr<const void, TestPluginFreeDeleter>;
/// Captures the most recent execute call for fake-plugin assertions.
///
/// Kept trivially destructible because instances are `thread_local` inside
/// plugin libraries; non-trivial destructors can register thread-exit
/// callbacks that keep POSIX libraries mapped after unload.
struct TestPluginLastCallRecord
{
TestPluginExecuteEntry whichEntry = TestPluginExecuteEntry::NONE;
void* workspace = nullptr;
uint32_t numOverrides = 0;
std::array<int64_t, K_MAX_TEST_OVERRIDES> capturedUniqueIds{};
std::array<uint32_t, K_MAX_TEST_OVERRIDES> capturedLengths{};
std::array<std::array<int64_t, K_MAX_TEST_OVERRIDE_RANK>, K_MAX_TEST_OVERRIDES>
capturedShapes{};
std::array<std::array<int64_t, K_MAX_TEST_OVERRIDE_RANK>, K_MAX_TEST_OVERRIDES>
capturedStrides{};
};
static_assert(std::is_trivially_destructible_v<TestPluginLastCallRecord>,
"TestPluginLastCallRecord must be trivially destructible. A non-trivial dtor "
"would register __cxa_thread_atexit callbacks for the per-plugin thread_local "
"instance, pinning the plugin .so under glibc and breaking "
"IntegrationSetPluginUnloadingModeExt.* unload checks.");
#ifdef HIPDNN_TEST_PLUGIN_BUILD
#define HIPDNN_TEST_PLUGIN_EXPORT HIPDNN_PLUGIN_EXPORT
#else
#define HIPDNN_TEST_PLUGIN_EXPORT
#endif
/// Defines per-plugin test observation storage and exported accessors.
#define DEFINE_TEST_PLUGIN_LAST_CALL_STORAGE(suffix) \
namespace \
{ \
thread_local TestPluginLastCallRecord s_record_##suffix; /* NOLINT */ \
} \
/* NOLINTBEGIN(readability-identifier-naming) suffixed C symbols */ \
/* Internal accessor used by the plugin's executeGraph* overrides. */ \
static inline TestPluginLastCallRecord& testPluginLastCallRecord_##suffix() \
{ \
return s_record_##suffix; \
} \
extern "C" HIPDNN_TEST_PLUGIN_EXPORT const TestPluginLastCallRecord* \
getLastCallRecord_##suffix() \
{ \
return &s_record_##suffix; \
} \
extern "C" HIPDNN_TEST_PLUGIN_EXPORT void resetLastCallRecord_##suffix() \
{ \
s_record_##suffix = TestPluginLastCallRecord{}; \
} \
/* NOLINTEND(readability-identifier-naming) */
// Per-plugin observation entry points. Tests resolve these against the
// plugin's own dynamic-loader handle.
// NOLINTBEGIN(readability-identifier-naming) - C symbol convention requires
// the underscore-suffixed form so dynamic-loader lookups match the per-plugin
// suffix passed to DEFINE_TEST_PLUGIN_LAST_CALL_STORAGE.
extern "C" HIPDNN_TEST_PLUGIN_EXPORT const TestPluginLastCallRecord*
getLastCallRecord_OverrideImplementing();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT void resetLastCallRecord_OverrideImplementing();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT const TestPluginLastCallRecord*
getLastCallRecord_OverrideOmitting();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT void resetLastCallRecord_OverrideOmitting();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT const TestPluginLastCallRecord*
getLastCallRecord_VersionLiar();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT void resetLastCallRecord_VersionLiar();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT const TestPluginLastCallRecord*
getLastCallRecord_SecondOverride();
extern "C" HIPDNN_TEST_PLUGIN_EXPORT void resetLastCallRecord_SecondOverride();
// NOLINTEND(readability-identifier-naming)
using TestPluginGetLastCallRecordFn = const TestPluginLastCallRecord* (*)();
using TestPluginResetLastCallRecordFn = void (*)();
namespace test_plugin_internal
{
/// Resolves relative plugin paths the same way the backend plugin loader does.
inline std::filesystem::path resolvePluginPathRelativeToBackend(const std::string& pluginPath)
{
std::filesystem::path requestedPath{pluginPath};
if(requestedPath.is_absolute())
{
return requestedPath;
}
#ifdef _WIN32
try
{
const auto backendDir = hipdnn_data_sdk::utilities::getLoadedLibraryDirectory(
hipdnn_data_sdk::utilities::getLibraryName("hipdnn_backend").c_str());
return std::filesystem::weakly_canonical(backendDir / requestedPath);
}
catch(const std::runtime_error&)
{
return requestedPath;
}
#else
try
{
const auto backendDir
= hipdnn_data_sdk::utilities::getLoadedLibraryDirectoryForSymbol("hipdnnCreate");
return std::filesystem::weakly_canonical(backendDir / requestedPath);
}
catch(const std::runtime_error&)
{
return requestedPath;
}
#endif
}
using TestPluginLibraryHandle = hipdnn_data_sdk::utilities::SharedLibraryHandle;
inline TestPluginLibraryHandle openPluginIfLoaded(const std::string& pluginPath)
{
const auto resolvedPath = resolvePluginPathRelativeToBackend(pluginPath);
return hipdnn_data_sdk::utilities::openLoadedLibrary(resolvedPath);
}
inline void* lookupPluginSymbol(TestPluginLibraryHandle handle, const std::string& symbolName)
{
return hipdnn_data_sdk::utilities::getSymbol(handle, symbolName.c_str());
}
} // namespace test_plugin_internal
class ScopedTestPluginLibrary
{
public:
explicit ScopedTestPluginLibrary(std::string pluginPath)
: _pluginPath(std::move(pluginPath))
{
const auto resolvedPath
= test_plugin_internal::resolvePluginPathRelativeToBackend(_pluginPath);
_handle = hipdnn_data_sdk::utilities::openLibrary(resolvedPath);
}
~ScopedTestPluginLibrary()
{
close();
}
ScopedTestPluginLibrary(const ScopedTestPluginLibrary&) = delete;
ScopedTestPluginLibrary& operator=(const ScopedTestPluginLibrary&) = delete;
ScopedTestPluginLibrary(ScopedTestPluginLibrary&& other) noexcept
: _pluginPath(std::move(other._pluginPath))
, _handle(std::exchange(other._handle, nullptr))
{
}
ScopedTestPluginLibrary& operator=(ScopedTestPluginLibrary&& other) noexcept
{
if(this != &other)
{
close();
_pluginPath = std::move(other._pluginPath);
_handle = std::exchange(other._handle, nullptr);
}
return *this;
}
template <typename Fn>
Fn lookup(const std::string& symbolName) const
{
if(_handle == nullptr)
{
return nullptr;
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return reinterpret_cast<Fn>(test_plugin_internal::lookupPluginSymbol(_handle, symbolName));
}
/// Like `lookup()`, but throws `std::runtime_error` when the symbol is
/// missing instead of returning nullptr. Use for mandatory recorder
/// symbols whose absence is a test-setup error.
template <typename Fn>
Fn requireSymbol(const char* symbolName) const
{
Fn fn = lookup<Fn>(symbolName);
if(fn == nullptr)
{
throw std::runtime_error("Failed to get symbol: " + std::string(symbolName));
}
return fn;
}
const std::string& pluginPath() const
{
return _pluginPath;
}
private:
void close()
{
if(_handle != nullptr)
{
hipdnn_data_sdk::utilities::closeLibrary(_handle);
_handle = nullptr;
}
}
std::string _pluginPath;
test_plugin_internal::TestPluginLibraryHandle _handle = nullptr;
};
inline TestPluginGetLastCallRecordFn
lookupLastCallRecordAccessor(const ScopedTestPluginLibrary& pluginLibrary,
const std::string& suffix)
{
const std::string symbolName = "getLastCallRecord_" + suffix;
return pluginLibrary.lookup<TestPluginGetLastCallRecordFn>(symbolName);
}
inline TestPluginResetLastCallRecordFn
lookupLastCallRecordResetter(const ScopedTestPluginLibrary& pluginLibrary,
const std::string& suffix)
{
const std::string symbolName = "resetLastCallRecord_" + suffix;
return pluginLibrary.lookup<TestPluginResetLastCallRecordFn>(symbolName);
}
inline void resetLastCallRecord(const ScopedTestPluginLibrary& pluginLibrary,
const std::string& suffix)
{
auto* fn = lookupLastCallRecordResetter(pluginLibrary, suffix);
if(fn != nullptr)
{
fn();
}
}
inline const TestPluginLastCallRecord*
getLastCallRecord(const ScopedTestPluginLibrary& pluginLibrary, const std::string& suffix)
{
auto* fn = lookupLastCallRecordAccessor(pluginLibrary, suffix);
return (fn != nullptr) ? fn() : nullptr;
}
/// Convenience: call `resetLastCallRecord_<suffix>()` if the symbol is
/// resolvable, otherwise no-op. Tests use this in fixture SetUp to wipe
/// TLS state across all fake plugins regardless of which subset is loaded.
inline void resetLastCallRecordIfLoaded(const std::string& pluginPath, const std::string& suffix)
{
auto handle = test_plugin_internal::openPluginIfLoaded(pluginPath);
if(handle == nullptr)
{
return;
}
const std::string symbolName = "resetLastCallRecord_" + suffix;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto* fn = reinterpret_cast<TestPluginResetLastCallRecordFn>(
test_plugin_internal::lookupPluginSymbol(handle, symbolName));
if(fn != nullptr)
{
fn();
}
hipdnn_data_sdk::utilities::closeLibrary(handle);
}
/// Convenience: call `getLastCallRecord_<suffix>()` if the symbol is
/// resolvable, otherwise return `nullptr`. Tests use this to inspect a
/// specific plugin's TLS observation record.
inline const TestPluginLastCallRecord* getLastCallRecordIfLoaded(const std::string& pluginPath,
const std::string& suffix)
{
auto handle = test_plugin_internal::openPluginIfLoaded(pluginPath);
if(handle == nullptr)
{
return nullptr;
}
const std::string symbolName = "getLastCallRecord_" + suffix;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto* fn = reinterpret_cast<TestPluginGetLastCallRecordFn>(
test_plugin_internal::lookupPluginSymbol(handle, symbolName));
const TestPluginLastCallRecord* record = (fn != nullptr) ? fn() : nullptr;
hipdnn_data_sdk::utilities::closeLibrary(handle);
return record;
}
// Base class for test plugins
class TestPluginBase
{
public:
virtual ~TestPluginBase() = default;
// Virtual methods to be overridden by derived classes
virtual const char* getPluginName() const = 0;
virtual const char* getPluginVersion() const = 0;
virtual const char* getPluginApiVersion() const = 0;
virtual int64_t getEngineId() const = 0;
virtual uint32_t getNumEngines() const = 0;
virtual uint32_t getNumApplicableEngines() const = 0;
virtual bool supportsEngineOperations() const
{
return getNumApplicableEngines() > 0;
}
// Execute graph - derived classes override this for custom behavior
virtual void executeGraph() const
{
HIPDNN_PLUGIN_LOG_INFO("executeGraph called");
}
/// Returns the calling thread's mutable last-call record for this plugin.
virtual TestPluginLastCallRecord& lastCallRecord() const
{
thread_local TestPluginLastCallRecord s_unused;
return s_unused;
}
/// Captures override-execute arguments for assertions.
virtual void executeGraphWithOverrides(uint32_t numOverrides,
const int64_t* overrideUniqueIds,
const uint32_t* overrideLengths,
const int64_t* const* overrideShapes,
const int64_t* const* overrideStrides) const
{
HIPDNN_PLUGIN_LOG_INFO("executeGraphWithOverrides called numOverrides=" << numOverrides);
constexpr auto MAX_TEST_OVERRIDES_U32 = static_cast<uint32_t>(K_MAX_TEST_OVERRIDES);
constexpr auto MAX_TEST_OVERRIDE_RANK_U32 = static_cast<uint32_t>(K_MAX_TEST_OVERRIDE_RANK);
if(numOverrides > MAX_TEST_OVERRIDES_U32)
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"Test plugin override capture capacity exceeded: numOverrides="
+ std::to_string(numOverrides)
+ ", capacity=" + std::to_string(K_MAX_TEST_OVERRIDES));
}
for(uint32_t i = 0; i < numOverrides; ++i)
{
if(overrideLengths[i] > MAX_TEST_OVERRIDE_RANK_U32)
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"Test plugin override rank capture capacity exceeded for index "
+ std::to_string(i) + ": rank=" + std::to_string(overrideLengths[i])
+ ", capacity=" + std::to_string(K_MAX_TEST_OVERRIDE_RANK));
}
}
auto& rec = lastCallRecord();
rec = TestPluginLastCallRecord{};
rec.whichEntry = TestPluginExecuteEntry::OP_GRAPH_WITH_OVERRIDES;
rec.numOverrides = numOverrides;
for(uint32_t i = 0; i < numOverrides; ++i)
{
rec.capturedUniqueIds[i] = overrideUniqueIds[i];
rec.capturedLengths[i] = overrideLengths[i];
for(uint32_t r = 0; r < overrideLengths[i]; ++r)
{
rec.capturedShapes[i][r] = overrideShapes[i][r];
rec.capturedStrides[i][r] = overrideStrides[i][r];
}
}
}
// Static instance management
static void setInstance(std::unique_ptr<TestPluginBase> instance)
{
s_instance = std::move(instance);
}
static TestPluginBase* getInstance()
{
return s_instance.get();
}
// Common API implementations
static hipdnnPluginStatus_t pluginGetName(const char** name)
{
LOG_API_ENTRY("namePtr=" << static_cast<const void*>(name));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(name);
hipdnn_plugin_sdk::throwIfNull(getInstance());
*name = getInstance()->getPluginName();
LOG_API_SUCCESS(apiName, "pluginName=" << static_cast<const void*>(name));
});
}
static hipdnnPluginStatus_t pluginGetVersion(const char** version)
{
LOG_API_ENTRY("versionPtr=" << static_cast<const void*>(version));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(version);
hipdnn_plugin_sdk::throwIfNull(getInstance());
*version = getInstance()->getPluginVersion();
LOG_API_SUCCESS(apiName, "version=" << static_cast<const void*>(version));
});
}
static hipdnnPluginStatus_t pluginGetApiVersion(const char** version)
{
LOG_API_ENTRY("versionPtr=" << static_cast<const void*>(version));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(version);
hipdnn_plugin_sdk::throwIfNull(getInstance());
*version = getInstance()->getPluginApiVersion();
LOG_API_SUCCESS(apiName, "version=" << static_cast<const void*>(version));
});
}
static hipdnnPluginStatus_t pluginGetType(hipdnnPluginType_t* type)
{
LOG_API_ENTRY("typePtr=" << static_cast<void*>(type));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(type);
*type = HIPDNN_PLUGIN_TYPE_ENGINE;
LOG_API_SUCCESS(apiName, "type=" << *type);
});
}
static void pluginGetLastErrorString(const char** errorStr)
{
LOG_API_ENTRY("errorStrPtr=" << static_cast<const void*>(errorStr));
hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(errorStr);
*errorStr = hipdnn_plugin_sdk::PluginLastErrorManager::getLastError();
LOG_API_SUCCESS(apiName, "errorStr=" << static_cast<const void*>(errorStr));
});
}
static hipdnnPluginStatus_t pluginSetLoggingCallback(hipdnnCallback_t callback)
{
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(callback);
hipdnn_plugin_sdk::throwIfNull(getInstance());
hipdnn_plugin_sdk::logging::initializeCallbackLogging(getInstance()->getPluginName(),
callback);
LOG_API_SUCCESS(apiName, "callback registered");
});
}
static hipdnnPluginStatus_t pluginSetLogLevel(hipdnnSeverity_t level)
{
return hipdnn_plugin_sdk::tryCatch([&]() {
hipdnn_plugin_sdk::throwIfNull(getInstance());
hipdnn_plugin_sdk::logging::setLogLevel(level);
// Log at the level being set so tests can positively verify the call
// and the level value for each severity
switch(level)
{
case HIPDNN_SEV_INFO:
HIPDNN_PLUGIN_LOG_INFO("TEST: pluginSetLogLevel level=" << level);
break;
case HIPDNN_SEV_WARN:
HIPDNN_PLUGIN_LOG_WARN("TEST: pluginSetLogLevel level=" << level);
break;
case HIPDNN_SEV_ERROR: // Not used by tests
case HIPDNN_SEV_FATAL: // Not used by tests
case HIPDNN_SEV_OFF:
default:
break;
}
});
}
static hipdnnPluginStatus_t
enginePluginGetAllEngineIds(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)
{
hipdnn_plugin_sdk::throwIfNull(engineIds);
}
hipdnn_plugin_sdk::throwIfNull(numEngines);
hipdnn_plugin_sdk::throwIfNull(getInstance());
*numEngines = getInstance()->getNumEngines();
if(maxEngines >= 1 && *numEngines > 0)
{
assert(*numEngines == 1);
engineIds[0] = getInstance()->getEngineId();
}
LOG_API_SUCCESS(apiName, "numEngines=" << *numEngines);
});
}
static hipdnnPluginStatus_t enginePluginCreate(hipdnnEnginePluginHandle_t* handle)
{
LOG_API_ENTRY("handlePtr=" << static_cast<void*>(handle));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
auto pluginHandle = std::make_unique<HipdnnEnginePluginHandle>();
*handle = pluginHandle.release();
LOG_API_SUCCESS(apiName, "createdHandle=" << static_cast<void*>(*handle));
});
}
static hipdnnPluginStatus_t enginePluginDestroy(hipdnnEnginePluginHandle_t handle)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
const std::unique_ptr<HipdnnEnginePluginHandle> pluginHandle(handle);
LOG_API_SUCCESS(apiName, "destroyed");
});
}
static hipdnnPluginStatus_t enginePluginSetStream(hipdnnEnginePluginHandle_t handle,
hipStream_t stream)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", streamId=" << static_cast<void*>(stream));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
LOG_API_SUCCESS(apiName, "stream set");
});
}
static hipdnnPluginStatus_t
enginePluginGetApplicableEngineIds(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(opGraph);
if(maxEngines != 0)
{
hipdnn_plugin_sdk::throwIfNull(engineIds);
}
hipdnn_plugin_sdk::throwIfNull(numEngines);
hipdnn_plugin_sdk::throwIfNull(getInstance());
*numEngines = getInstance()->getNumApplicableEngines();
if(maxEngines >= 1 && *numEngines > 0)
{
engineIds[0] = getInstance()->getEngineId();
}
LOG_API_SUCCESS(apiName, "numEngines=" << *numEngines);
});
}
static hipdnnPluginStatus_t enginePluginGetEngineDetails(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(opGraph);
hipdnn_plugin_sdk::throwIfNull(engineDetails);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot get engine details");
}
flatbuffers::FlatBufferBuilder builder;
// This plugin serializes execution plans, so it advertises the note
// the frontend checks before serializing a plan alongside the graph.
const std::vector<int32_t> behaviorNotes{
static_cast<int32_t>(HIPDNN_BEHAVIOR_NOTE_SUPPORTS_EXECUTION_PLAN_SERIALIZATION)};
auto newEngineDetails = hipdnn_flatbuffers_sdk::data_objects::CreateEngineDetailsDirect(
builder, getInstance()->getEngineId(), nullptr, &behaviorNotes);
builder.Finish(newEngineDetails);
auto serializedDetails = builder.Release();
TestPluginMallocBuffer tempBuffer(std::malloc(serializedDetails.size()));
hipdnn_plugin_sdk::throwIfNull(tempBuffer.get());
std::memcpy(tempBuffer.get(), serializedDetails.data(), serializedDetails.size());
engineDetails->ptr = tempBuffer.release();
engineDetails->size = serializedDetails.size();
LOG_API_SUCCESS(apiName, "engineDetails->ptr=" << engineDetails->ptr);
});
}
static hipdnnPluginStatus_t
enginePluginDestroyEngineDetails(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(engineDetails);
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engine details to destroy");
}
hipdnn_plugin_sdk::throwIfNull(engineDetails->ptr);
const TestPluginConstMallocBuffer engineDetailsBytes(engineDetails->ptr);
engineDetails->ptr = nullptr;
engineDetails->size = 0;
LOG_API_SUCCESS(apiName, "engineDetails->ptr=" << engineDetails->ptr);
});
}
static hipdnnPluginStatus_t
enginePluginGetWorkspaceSize(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(engineConfig);
hipdnn_plugin_sdk::throwIfNull(opGraph);
hipdnn_plugin_sdk::throwIfNull(workspaceSize);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot get workspace size");
}
*workspaceSize = 1024;
LOG_API_SUCCESS(apiName, "workspaceSize=" << *workspaceSize);
});
}
static hipdnnPluginStatus_t
enginePluginGetWorkspaceSize(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(workspaceSize);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot get workspace size");
}
*workspaceSize = 2048;
LOG_API_SUCCESS(apiName, "workspaceSize=" << *workspaceSize);
});
}
static hipdnnPluginStatus_t
enginePluginCreateExecutionContext(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(engineConfig);
hipdnn_plugin_sdk::throwIfNull(opGraph);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot create execution context");
}
const hipdnn_flatbuffers_sdk::flatbuffer_utilities::GraphWrapper opGraphWrapper(
opGraph->ptr, opGraph->size);
const hipdnn_flatbuffers_sdk::flatbuffer_utilities::EngineConfigWrapper
engineConfigWrapper(engineConfig->ptr, engineConfig->size);
auto context = std::make_unique<HipdnnEnginePluginExecutionContext>();
context->engineId = engineConfigWrapper.engineId();
*executionContext = context.release();
LOG_API_SUCCESS(apiName,
"createdExecutionContext=" << static_cast<void*>(*executionContext));
});
}
static hipdnnPluginStatus_t
enginePluginDestroyExecutionContext(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No execution context to destroy");
}
const std::unique_ptr<HipdnnEnginePluginExecutionContext> context(executionContext);
LOG_API_SUCCESS(apiName, "destroyed executionContext");
});
}
static hipdnnPluginStatus_t
enginePluginSerializeExecutionContext(hipdnnEnginePluginHandle_t handle,
hipdnnEnginePluginExecutionContext_t executionContext,
hipdnnPluginConstData_t* serializedContext)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", executionContext=" << static_cast<void*>(executionContext)
<< ", serializedContext=" << static_cast<void*>(serializedContext));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(serializedContext);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No execution context available to serialize");
}
auto payload = std::make_unique<TestPluginSerializedContextPayload>();
(*payload)[0] = 0x42;
LOG_API_SUCCESS(apiName, "serialized context");
serializedContext->ptr = payload.release();
serializedContext->size = sizeof(TestPluginSerializedContextPayload);
});
}
static hipdnnPluginStatus_t
enginePluginDestroySerializedExecutionContext(hipdnnEnginePluginHandle_t handle,
hipdnnPluginConstData_t* serializedContext)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", serializedContext=" << static_cast<void*>(serializedContext));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(serializedContext);
hipdnn_plugin_sdk::throwIfNull(serializedContext->ptr);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No serialized execution context to destroy");
}
const std::unique_ptr<const TestPluginSerializedContextPayload> payload(
static_cast<const TestPluginSerializedContextPayload*>(serializedContext->ptr));
serializedContext->ptr = nullptr;
serializedContext->size = 0;
LOG_API_SUCCESS(apiName, "destroyed serialized context");
});
}
static hipdnnPluginStatus_t enginePluginCreateExecutionContextFromSerialized(
hipdnnEnginePluginHandle_t handle,
const hipdnnPluginConstData_t* serializedContext,
hipdnnEnginePluginExecutionContext_t* executionContext)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle) << ", serializedContext="
<< static_cast<const void*>(serializedContext)
<< ", executionContext=" << static_cast<void*>(executionContext));
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(serializedContext);
hipdnn_plugin_sdk::throwIfNull(serializedContext->ptr);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot create execution context from serialized data");
}
const auto* payload
= static_cast<const TestPluginSerializedContextPayload*>(serializedContext->ptr);
if(serializedContext->size != sizeof(TestPluginSerializedContextPayload)
|| (*payload)[0] != 0x42)
{
const auto firstByte
= serializedContext->size > 0
? static_cast<int>(static_cast<const uint8_t*>(serializedContext->ptr)[0])
: -1;
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
std::string("Serialized execution context payload is malformed for plugin ")
+ getInstance()->getPluginName()
+ ": size=" + std::to_string(serializedContext->size) + ", expected_size="
+ std::to_string(sizeof(TestPluginSerializedContextPayload))
+ ", first_byte=" + std::to_string(firstByte) + ", expected_first_byte=66");
}
auto context = std::make_unique<HipdnnEnginePluginExecutionContext>();
LOG_API_SUCCESS(apiName,
"createdExecutionContext=" << static_cast<void*>(context.get()));
*executionContext = context.release();
});
}
static hipdnnPluginStatus_t
enginePluginExecuteOpGraph(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__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(deviceBuffers);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot execute graph");
}
auto& rec = getInstance()->lastCallRecord();
rec = TestPluginLastCallRecord{};
rec.whichEntry = TestPluginExecuteEntry::OP_GRAPH;
rec.workspace = workspace;
getInstance()->executeGraph();
LOG_API_SUCCESS(apiName, "executed graph");
});
}
/// Shared C-API implementation used by fake plugins that export override execute.
static hipdnnPluginStatus_t enginePluginExecuteOpGraphWithOverrides(
hipdnnEnginePluginHandle_t handle,
hipdnnEnginePluginExecutionContext_t executionContext,
void* workspace,
const hipdnnPluginDeviceBuffer_t* deviceBuffers,
uint32_t numDeviceBuffers,
uint32_t numOverrides,
const int64_t* overrideUniqueIds,
const uint32_t* overrideLengths,
const int64_t* const* overrideShapes,
const int64_t* const* overrideStrides)
{
LOG_API_ENTRY("handle=" << static_cast<void*>(handle)
<< ", executionContext=" << static_cast<void*>(executionContext)
<< ", workspace=" << workspace
<< ", deviceBuffers=" << static_cast<const void*>(deviceBuffers)
<< ", numDeviceBuffers=" << numDeviceBuffers
<< ", numOverrides=" << numOverrides);
return hipdnn_plugin_sdk::tryCatch([&, apiName = __func__]() {
hipdnn_plugin_sdk::throwIfNull(handle);
hipdnn_plugin_sdk::throwIfNull(executionContext);
hipdnn_plugin_sdk::throwIfNull(deviceBuffers);
hipdnn_plugin_sdk::throwIfNull(getInstance());
if(numOverrides > 0)
{
hipdnn_plugin_sdk::throwIfNull(overrideUniqueIds);
hipdnn_plugin_sdk::throwIfNull(overrideLengths);
hipdnn_plugin_sdk::throwIfNull(overrideShapes);
hipdnn_plugin_sdk::throwIfNull(overrideStrides);
}
if(!getInstance()->supportsEngineOperations())
{
throw hipdnn_plugin_sdk::HipdnnPluginException(
HIPDNN_PLUGIN_STATUS_INTERNAL_ERROR,
"No engines available - cannot execute graph with overrides");
}
getInstance()->executeGraphWithOverrides(
numOverrides, overrideUniqueIds, overrideLengths, overrideShapes, overrideStrides);
getInstance()->lastCallRecord().workspace = workspace;
LOG_API_SUCCESS(apiName, "executed graph with overrides");
});
}
private:
inline static std::unique_ptr<TestPluginBase> s_instance; //NOLINT
};
// Macro to register plugin API functions
#define REGISTER_TEST_PLUGIN_API() \
extern "C" { \
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginGetName(const char** name) \
{ \
return TestPluginBase::pluginGetName(name); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginGetVersion(const char** version) \
{ \
return TestPluginBase::pluginGetVersion(version); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginGetApiVersion(const char** version) \
{ \
return TestPluginBase::pluginGetApiVersion(version); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginGetType(hipdnnPluginType_t* type) \
{ \
return TestPluginBase::pluginGetType(type); \
} \
\
HIPDNN_TEST_PLUGIN_EXPORT void hipdnnPluginGetLastErrorString(const char** errorStr) \
{ \
TestPluginBase::pluginGetLastErrorString(errorStr); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginSetLoggingCallback(hipdnnCallback_t callback) \
{ \
return TestPluginBase::pluginSetLoggingCallback(callback); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnPluginSetLogLevel(hipdnnSeverity_t level) \
{ \
return TestPluginBase::pluginSetLogLevel(level); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginGetAllEngineIds(int64_t* engineIds, \
uint32_t maxEngines, \
uint32_t* numEngines) \
{ \
return TestPluginBase::enginePluginGetAllEngineIds(engineIds, maxEngines, numEngines); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginCreate(hipdnnEnginePluginHandle_t* handle) \
{ \
return TestPluginBase::enginePluginCreate(handle); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginDestroy(hipdnnEnginePluginHandle_t handle) \
{ \
return TestPluginBase::enginePluginDestroy(handle); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginSetStream(hipdnnEnginePluginHandle_t handle, hipStream_t stream) \
{ \
return TestPluginBase::enginePluginSetStream(handle, stream); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginGetApplicableEngineIds(hipdnnEnginePluginHandle_t handle, \
const hipdnnPluginConstData_t* opGraph, \
int64_t* engineIds, \
uint32_t maxEngines, \
uint32_t* numEngines) \
{ \
return TestPluginBase::enginePluginGetApplicableEngineIds( \
handle, opGraph, engineIds, maxEngines, numEngines); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginGetEngineDetails(hipdnnEnginePluginHandle_t handle, \
int64_t engineId, \
const hipdnnPluginConstData_t* opGraph, \
hipdnnPluginConstData_t* engineDetails) \
{ \
return TestPluginBase::enginePluginGetEngineDetails( \
handle, engineId, opGraph, engineDetails); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginDestroyEngineDetails(hipdnnEnginePluginHandle_t handle, \
hipdnnPluginConstData_t* engineDetails) \
{ \
return TestPluginBase::enginePluginDestroyEngineDetails(handle, engineDetails); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginGetWorkspaceSize(hipdnnEnginePluginHandle_t handle, \
const hipdnnPluginConstData_t* engineConfig, \
const hipdnnPluginConstData_t* opGraph, \
size_t* workspaceSize) \
{ \
return TestPluginBase::enginePluginGetWorkspaceSize( \
handle, engineConfig, opGraph, workspaceSize); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginGetWorkspaceSizeFromExecutionContext( \
hipdnnEnginePluginHandle_t handle, \
hipdnnEnginePluginExecutionContext_t executionContext, \
size_t* workspaceSize) \
{ \
return TestPluginBase::enginePluginGetWorkspaceSize( \
handle, executionContext, workspaceSize); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginCreateExecutionContext( \
hipdnnEnginePluginHandle_t handle, \
const hipdnnPluginConstData_t* engineConfig, \
const hipdnnPluginConstData_t* opGraph, \
hipdnnEnginePluginExecutionContext_t* executionContext) \
{ \
return TestPluginBase::enginePluginCreateExecutionContext( \
handle, engineConfig, opGraph, executionContext); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginDestroyExecutionContext( \
hipdnnEnginePluginHandle_t handle, \
hipdnnEnginePluginExecutionContext_t executionContext) \
{ \
return TestPluginBase::enginePluginDestroyExecutionContext(handle, executionContext); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginSerializeExecutionContext( \
hipdnnEnginePluginHandle_t handle, \
hipdnnEnginePluginExecutionContext_t executionContext, \
hipdnnPluginConstData_t* serializedContext) \
{ \
return TestPluginBase::enginePluginSerializeExecutionContext( \
handle, executionContext, serializedContext); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginDestroySerializedExecutionContext( \
hipdnnEnginePluginHandle_t handle, hipdnnPluginConstData_t* serializedContext) \
{ \
return TestPluginBase::enginePluginDestroySerializedExecutionContext(handle, \
serializedContext); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginCreateExecutionContextFromSerialized( \
hipdnnEnginePluginHandle_t handle, \
const hipdnnPluginConstData_t* serializedContext, \
hipdnnEnginePluginExecutionContext_t* executionContext) \
{ \
return TestPluginBase::enginePluginCreateExecutionContextFromSerialized( \
handle, serializedContext, executionContext); \
} \
\
HIPDNN_PLUGIN_NODISCARD HIPDNN_TEST_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginExecuteOpGraph(hipdnnEnginePluginHandle_t handle, \
hipdnnEnginePluginExecutionContext_t executionContext, \
void* workspace, \
const hipdnnPluginDeviceBuffer_t* deviceBuffers, \
uint32_t numDeviceBuffers) \
{ \
return TestPluginBase::enginePluginExecuteOpGraph( \
handle, executionContext, workspace, deviceBuffers, numDeviceBuffers); \
} \
} // extern "C"
/// Emits only the optional override-execute C symbol for fake plugins.
#define REGISTER_TEST_PLUGIN_OVERRIDE_API() \
extern "C" { \
HIPDNN_PLUGIN_NODISCARD HIPDNN_PLUGIN_EXPORT hipdnnPluginStatus_t \
hipdnnEnginePluginExecuteOpGraphWithOverrides( \
hipdnnEnginePluginHandle_t handle, \
hipdnnEnginePluginExecutionContext_t executionContext, \
void* workspace, \
const hipdnnPluginDeviceBuffer_t* deviceBuffers, \
uint32_t numDeviceBuffers, \
uint32_t numOverrides, \
const int64_t* overrideUniqueIds, \
const uint32_t* overrideLengths, \
const int64_t* const* overrideShapes, \
const int64_t* const* overrideStrides) \
{ \
return TestPluginBase::enginePluginExecuteOpGraphWithOverrides(handle, \
executionContext, \
workspace, \
deviceBuffers, \
numDeviceBuffers, \
numOverrides, \
overrideUniqueIds, \
overrideLengths, \
overrideShapes, \
overrideStrides); \
} \
} // extern "C"