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
307 lines
10 KiB
C++
307 lines
10 KiB
C++
// Copyright © Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "DescriptorTestUtils.hpp"
|
|
#include "TestMacros.hpp"
|
|
#include "descriptors/ProfilingControlDescriptor.hpp"
|
|
#include "hipdnn_backend.h"
|
|
#include "mocks/MockHandle.hpp"
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <hipdnn_test_sdk/utilities/TestUtilities.hpp>
|
|
|
|
#include <string>
|
|
|
|
using namespace hipdnn_backend;
|
|
using namespace hipdnn_backend::test_utilities;
|
|
using ::testing::NiceMock;
|
|
using ::testing::Return;
|
|
|
|
class TestProfilingControlDescriptor : public ::testing::Test
|
|
{
|
|
public:
|
|
std::shared_ptr<ProfilingControlDescriptor> getDescriptor() const
|
|
{
|
|
return _wrapper->asDescriptor<ProfilingControlDescriptor>();
|
|
}
|
|
|
|
protected:
|
|
std::unique_ptr<HipdnnBackendDescriptor> _wrapper = nullptr;
|
|
|
|
void SetUp() override
|
|
{
|
|
_wrapper = createDescriptor<ProfilingControlDescriptor>();
|
|
}
|
|
|
|
void TearDown() override
|
|
{
|
|
_wrapper.reset();
|
|
}
|
|
};
|
|
|
|
TEST_F(TestProfilingControlDescriptor, CreateDescriptor)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NE(desc, nullptr);
|
|
ASSERT_FALSE(desc->isFinalized());
|
|
ASSERT_EQ(desc->getType(), HIPDNN_BACKEND_PROFILING_CONTROL_EXT);
|
|
}
|
|
|
|
// Guards against a silent 1/0 render of the boolean state fields in toString():
|
|
// a freshly created descriptor has all state flags false, so each must render as
|
|
// the literal token "false" (never "0" / "1").
|
|
TEST_F(TestProfilingControlDescriptor, ToStringRendersBooleanTokens)
|
|
{
|
|
const std::string str = getDescriptor()->toString();
|
|
|
|
EXPECT_NE(str.find("eventsCreated=false"), std::string::npos);
|
|
EXPECT_NE(str.find("startRecorded=false"), std::string::npos);
|
|
EXPECT_NE(str.find("stopRecorded=false"), std::string::npos);
|
|
EXPECT_NE(str.find("finalized=false"), std::string::npos);
|
|
|
|
EXPECT_EQ(str.find("eventsCreated=0"), std::string::npos);
|
|
EXPECT_EQ(str.find("eventsCreated=1"), std::string::npos);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Base-fixture guard coverage (no GPU)
|
|
//
|
|
// Each case targets a guard that throws before any hip* call, so a handle is
|
|
// never set and no device events are created. These run on every CI runner.
|
|
// For START/STOP the guard order is checkSetArgs(type) -> elementCount ->
|
|
// handle-set -> recorded-state, so each assertion targets the first guard that
|
|
// fires for the supplied inputs.
|
|
// ============================================================================
|
|
|
|
TEST_F(TestProfilingControlDescriptor, SetStartBeforeHandleThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, SetStopBeforeHandleThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_STOP_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, SetAttributeWrongElementCountThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
// elementCount=2 fails the count guard (after the type check passes).
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_BOOLEAN, 2, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_STOP_EXT, HIPDNN_TYPE_BOOLEAN, 2, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, SetAttributeTypeMismatchThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
// Wrong value type fails checkSetArgs (the first guard) for a boolean attr.
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_INT64, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, SetAttributeUnsupportedNameThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_ENGINE_GLOBAL_INDEX, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_NOT_SUPPORTED);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, GetAttributeBeforeFinalizeThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
float elapsed = 0.0f;
|
|
int64_t elementCount = 0;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->getAttribute(
|
|
HIPDNN_ATTR_PROFILING_ELAPSED_MS_EXT, HIPDNN_TYPE_FLOAT, 1, &elementCount, &elapsed),
|
|
HIPDNN_STATUS_NOT_INITIALIZED);
|
|
}
|
|
|
|
TEST_F(TestProfilingControlDescriptor, FinalizeBeforeHandleThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
// Fresh descriptor: not finalized, but no handle/events created.
|
|
ASSERT_THROW_HIPDNN_STATUS(desc->finalize(), HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
// ============================================================================
|
|
// GPU-requiring lifecycle coverage
|
|
//
|
|
// Setting a handle creates real hipEvents on the device, so these tests need a
|
|
// device and are skipped on no-GPU runners via SKIP_IF_NO_DEVICES(). Mirrors
|
|
// TestGpuEngineHeuristicDescriptor.
|
|
// ============================================================================
|
|
|
|
class TestGpuProfilingControlDescriptor : public TestProfilingControlDescriptor
|
|
{
|
|
protected:
|
|
void SetUp() override
|
|
{
|
|
SKIP_IF_NO_DEVICES();
|
|
TestProfilingControlDescriptor::SetUp();
|
|
ASSERT_EQ(hipStreamCreate(&_testStream), hipSuccess);
|
|
_mockHandle = std::make_unique<NiceMock<MockHandle>>();
|
|
ON_CALL(*_mockHandle, getStream()).WillByDefault(Return(_testStream));
|
|
}
|
|
|
|
void TearDown() override
|
|
{
|
|
_mockHandle.reset();
|
|
if(_testStream != nullptr)
|
|
{
|
|
EXPECT_EQ(hipStreamDestroy(_testStream), hipSuccess);
|
|
_testStream = nullptr;
|
|
}
|
|
TestProfilingControlDescriptor::TearDown();
|
|
}
|
|
|
|
// Sets the handle on the descriptor, which creates the device events.
|
|
void setHandle(const std::shared_ptr<ProfilingControlDescriptor>& desc) const
|
|
{
|
|
hipdnnHandle* handlePtr = _mockHandle.get();
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_HANDLE_EXT,
|
|
HIPDNN_TYPE_HANDLE,
|
|
1,
|
|
static_cast<const void*>(&handlePtr));
|
|
}
|
|
|
|
static void recordStart(const std::shared_ptr<ProfilingControlDescriptor>& desc)
|
|
{
|
|
bool value = true;
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value);
|
|
}
|
|
|
|
static void recordStop(const std::shared_ptr<ProfilingControlDescriptor>& desc)
|
|
{
|
|
bool value = true;
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_STOP_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value);
|
|
}
|
|
|
|
std::unique_ptr<NiceMock<MockHandle>> _mockHandle = nullptr;
|
|
hipStream_t _testStream = nullptr;
|
|
};
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, HappyPathCompletesLifecycle)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_NO_THROW(recordStop(desc));
|
|
ASSERT_NO_THROW(desc->finalize());
|
|
|
|
// getAttribute(ELAPSED_MS) round-trips: no throw, one element written.
|
|
// The elapsed value itself is driver-provided and not asserted.
|
|
float elapsed = -1.0f;
|
|
int64_t elementCount = 0;
|
|
ASSERT_NO_THROW(desc->getAttribute(
|
|
HIPDNN_ATTR_PROFILING_ELAPSED_MS_EXT, HIPDNN_TYPE_FLOAT, 1, &elementCount, &elapsed));
|
|
EXPECT_EQ(elementCount, 1);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, StartRecordedTwiceThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, StopBeforeStartThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_STOP_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, StopRecordedTwiceThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_NO_THROW(recordStop(desc));
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_STOP_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, SetAttributeAfterFinalizeThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_NO_THROW(recordStop(desc));
|
|
ASSERT_NO_THROW(desc->finalize());
|
|
bool value = true;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_START_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value),
|
|
HIPDNN_STATUS_NOT_INITIALIZED);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, FinalizeAlreadyFinalizedThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_NO_THROW(recordStop(desc));
|
|
ASSERT_NO_THROW(desc->finalize());
|
|
ASSERT_THROW_HIPDNN_STATUS(desc->finalize(), HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, FinalizeWithoutStopRecordedThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_THROW_HIPDNN_STATUS(desc->finalize(), HIPDNN_STATUS_BAD_PARAM);
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, DeviceSyncSucceeds)
|
|
{
|
|
auto desc = getDescriptor();
|
|
bool value = true;
|
|
ASSERT_NO_THROW(
|
|
desc->setAttribute(HIPDNN_ATTR_PROFILING_DEVICE_SYNC_EXT, HIPDNN_TYPE_BOOLEAN, 1, &value));
|
|
}
|
|
|
|
TEST_F(TestGpuProfilingControlDescriptor, GetAttributeUnsupportedNameThrows)
|
|
{
|
|
auto desc = getDescriptor();
|
|
ASSERT_NO_THROW(setHandle(desc));
|
|
ASSERT_NO_THROW(recordStart(desc));
|
|
ASSERT_NO_THROW(recordStop(desc));
|
|
ASSERT_NO_THROW(desc->finalize());
|
|
|
|
// On a finalized descriptor, an unrelated attribute name hits the
|
|
// unsupported-name guard past the finalized check.
|
|
int64_t value = 0;
|
|
int64_t elementCount = 0;
|
|
ASSERT_THROW_HIPDNN_STATUS(
|
|
desc->getAttribute(
|
|
HIPDNN_ATTR_ENGINE_GLOBAL_INDEX, HIPDNN_TYPE_INT64, 1, &elementCount, &value),
|
|
HIPDNN_STATUS_NOT_SUPPORTED);
|
|
}
|